def _create_iso_candidates(self, tube_rack_fac, tube_rack_specs_matrix, tube_fac, item_status_managed, organization_cenix, stock_sample_fac): ss_agg = get_root_aggregate(IStockSample) rack_agg = get_root_aggregate(IRack) tube_bc = 9000000000 vol = 1e-4 row_idx = 0 col_idx = 0 tube_rack = tube_rack_fac(label='test_iso_candidates', specs=tube_rack_specs_matrix, status=get_item_status_managed()) rack_agg.add(tube_rack) mdp_agg = get_root_aggregate(IMoleculeDesignPool) for mdp_id in [288282, 3349397, 3430173, 1139866, 199937]: tube = tube_fac(barcode=str(tube_bc), status=item_status_managed) col_idx += 1 tube_bc += 1 tube_rack.add_tube( tube, get_rack_position_from_indices(row_idx, col_idx)) mdp = mdp_agg.get_by_id(mdp_id) ss = stock_sample_fac( volume=vol, container=tube, molecule_design_pool=mdp, supplier=organization_cenix, molecule_type=mdp.molecule_type, concentration=mdp.default_stock_concentration) ss_agg.add(ss)
def __get_empty_racks(self, count): rack_specs_agg = get_root_aggregate(ITubeRackSpecs) rs_matrix = rack_specs_agg.get_by_slug('matrix0500') is_managed = get_item_status_managed() rack_agg = get_root_aggregate(ITubeRack) rack_agg.filter = eq(total_containers=0, specs=rs_matrix, status=is_managed) rack_agg.slice = slice(0, count) return list(iter(rack_agg))
def run(self): self.add_info('Running molecule design registrar.') self.__check_new_molecule_designs() cs_agg = get_root_aggregate(IChemicalStructure) md_agg = get_root_aggregate(IMoleculeDesign) cs_keys = set() new_css = set() new_mds = set() # Build keys for all new chemical structures. for mdris in self.__new_mdris: # By definition, all mdris for a given hash have the same # structures, so we just take the first. for cs in mdris[0].chemical_structures: cs_keys.add((cs.structure_type_id, cs.representation)) # FIXME: Build a single filtering spec here (see FIXME above). cs_map = {} for cs_key in cs_keys: sti, rpr = cs_key spec = eq(structure_type_id=sti, representation=rpr) cs_agg.filter = spec try: cs = cs_agg.iterator().next() except StopIteration: continue else: cs_map[cs_key] = cs self.add_debug('Creating %d new molecule designs.' % len(self.__new_mdris)) for mdris in self.__new_mdris: md_structs = [] # By definition, all mdris for a given hash have the same # structures, so we just take the first. for struct in mdris[0].chemical_structures: key = (struct.structure_type_id, struct.representation) if not key in cs_map: # New chemical structure - add and use for the design. cs_agg.add(struct) new_css.add(struct) md_structs.append(struct) cs_map[key] = struct else: # Use existing structure for the design. md_structs.append(cs_map[key]) # Create the new design. md = MoleculeDesign.create_from_data( dict(molecule_type=mdris[0].molecule_type, chemical_structures=md_structs)) md_agg.add(md) new_mds.add(md) # Update registration items. for mdri in mdris: mdri.molecule_design = md self.return_value = dict(molecule_designs=new_mds, chemical_structures=new_css)
def run(self): rack_agg = get_root_aggregate(IRack) is_agg = get_root_aggregate(IItemStatus) status = is_agg.get_by_slug(self.STATUS) cnt_specs_agg = get_root_aggregate(IContainerSpecs) cnt_specs = cnt_specs_agg.get_by_slug(self.SPECS) tubes = [] for scan_fn in glob.glob("%s/*.txt" % self.__scanfile_directory): strm = open(scan_fn, 'r') try: prs = RackScanningParser(strm, parent=self) prs.run() finally: strm.close() if prs.has_errors(): raise RuntimeError('Could not parse rack scan file "%s". ' 'Error messages: %s' % (scan_fn, self.get_messages())) rack_agg.filter = eq(barcode=prs.rack_barcode) try: rack = rack_agg.iterator().next() except StopIteration: self.add_error('Rack with barcode "%s" does not exist.' % prs.rack_barcode) continue if not rack.specs.has_tubes: self.add_error('Rack with barcode "%s" is not a tube ' 'rack.' % rack.barcode) continue for pos_label, barcode in prs.position_map.iteritems(): if barcode is None: continue pos = get_rack_position_from_label(pos_label) # FIXME: Enable this test once pulling a tube by barcode is # fast. # if tube_agg.get_by_slug(barcode): # self.add_error('Tube with barcode "%s" already ' # 'exists.' % barcode) # continue if not rack.is_empty(pos): self.add_error('Trying to place a tube in an occupied ' 'position (%s on rack %s).' % (pos_label, rack.barcode)) continue tube = Tube.create_from_rack_and_position( cnt_specs, status, barcode, rack, pos) tubes.append(tube) self.add_info('Creating tube with barcode %s at ' 'position %s in rack %s.' % (barcode, pos_label, rack.barcode)) if not self.has_errors(): self.return_value = tubes
def run(self): rack_agg = get_root_aggregate(IRack) is_agg = get_root_aggregate(IItemStatus) status = is_agg.get_by_slug(self.STATUS) cnt_specs_agg = get_root_aggregate(IContainerSpecs) cnt_specs = cnt_specs_agg.get_by_slug(self.SPECS) tubes = [] for scan_fn in glob.glob("%s/*.txt" % self.__scanfile_directory): strm = open(scan_fn, 'r') try: prs = RackScanningParser(strm, parent=self) prs.run() finally: strm.close() if prs.has_errors(): raise RuntimeError('Could not parse rack scan file "%s". ' 'Error messages: %s' % (scan_fn, self.get_messages())) rack_agg.filter = eq(barcode=prs.rack_barcode) try: rack = rack_agg.iterator().next() except StopIteration: self.add_error('Rack with barcode "%s" does not exist.' % prs.rack_barcode) continue if not rack.specs.has_tubes: self.add_error('Rack with barcode "%s" is not a tube ' 'rack.' % rack.barcode) continue for pos_label, barcode in prs.position_map.iteritems(): if barcode is None: continue pos = get_rack_position_from_label(pos_label) # FIXME: Enable this test once pulling a tube by barcode is # fast. # if tube_agg.get_by_slug(barcode): # self.add_error('Tube with barcode "%s" already ' # 'exists.' % barcode) # continue if not rack.is_empty(pos): self.add_error('Trying to place a tube in an occupied ' 'position (%s on rack %s).' % (pos_label, rack.barcode)) continue tube = Tube.create_from_rack_and_position(cnt_specs, status, barcode, rack, pos) tubes.append(tube) self.add_info('Creating tube with barcode %s at ' 'position %s in rack %s.' % (barcode, pos_label, rack.barcode)) if not self.has_errors(): self.return_value = tubes
def __prepare_semiconstants(self): self.add_debug('Preparing semiconstants.') container_specs_agg = get_root_aggregate(IContainerSpecs) self.__container_specs = container_specs_agg.get_by_slug( self.__container_specs_name) self.__tube_check_needed = self.__container_specs.has_barcode rack_specs_agg = get_root_aggregate(IRackSpecs) self.__rack_specs = rack_specs_agg.get_by_slug(self.__rack_specs_name) if self.__tube_check_needed != self.__rack_specs.has_tubes: raise ValueError('Inconsistency in rack and tube specs detected.') item_status_agg = get_root_aggregate(IItemStatus) self.__status = item_status_agg.get_by_slug( ITEM_STATUS_NAMES.MANAGED.lower())
def _upload_metadata(self, xls_filename, scenario, app): # First, create a new metadata entity and POST it. emd_coll = create_staging_collection(IExperimentMetadata) emd = ExperimentMetadata('unit_test_metadata', next(iter(get_root_aggregate(ISubproject))), 1, get_experiment_metadata_type(scenario) ) mb_emd = emd_coll.create_member(emd) rpr = as_representer(mb_emd, XmlMime) emd_rpr = rpr.to_string(mb_emd) res = app.post("/%s" % emd_coll.__name__, params=emd_rpr, content_type=XmlMime.mime_type_string, status=HTTPCreated.code) self.__session.commit() mb_url = res.headers['Location'] # Now, PUT the excel meta data file. self.__session.begin_nested() with open(xls_filename, 'rb') as xls_file: res = app.put(mb_url, params=xls_file.read(), content_type=XlsMime.mime_type_string) # If the file had warnings, we have to repeat the PUT. if res.status.endswith(HTTPTemporaryRedirect.title): self.__session.rollback() # 307 Redirect: Repeat with warnings disabled. with open(xls_filename, 'rb') as xls_file: res = app.put(res.headers['Location'], params=xls_file.read(), content_type=XlsMime.mime_type_string, status=HTTPOk.code) self.__session.commit() assert res.status.endswith(HTTPOk.title) return mb_url
def _upload_metadata(self, xls_filename, scenario, app): # First, create a new metadata entity and POST it. emd_coll = create_staging_collection(IExperimentMetadata) emd = ExperimentMetadata('unit_test_metadata', next(iter(get_root_aggregate(ISubproject))), 1, get_experiment_metadata_type(scenario)) mb_emd = emd_coll.create_member(emd) rpr = as_representer(mb_emd, XmlMime) emd_rpr = rpr.to_string(mb_emd) res = app.post("/%s" % emd_coll.__name__, params=emd_rpr, content_type=XmlMime.mime_type_string, status=HTTPCreated.code) self.__session.commit() mb_url = res.headers['Location'] # Now, PUT the excel meta data file. self.__session.begin_nested() with open(xls_filename, 'rb') as xls_file: res = app.put(mb_url, params=xls_file.read(), content_type=XlsMime.mime_type_string) # If the file had warnings, we have to repeat the PUT. if res.status.endswith(HTTPTemporaryRedirect.title): self.__session.rollback() # 307 Redirect: Repeat with warnings disabled. with open(xls_filename, 'rb') as xls_file: res = app.put(res.headers['Location'], params=xls_file.read(), content_type=XlsMime.mime_type_string, status=HTTPOk.code) self.__session.commit() assert res.status.endswith(HTTPOk.title) return mb_url
def __fetch_tubes(self): # Fetches tube (for location data), from the the DB. Uses the tube # barcodes from the library layouts. self.add_debug('Fetch tubes ...') tube_barcodes = [] for lib_pos in self.__library_layout.working_positions(): for barcode in lib_pos.stock_tube_barcodes: tube_barcodes.append(barcode) tube_agg = get_root_aggregate(ITube) tube_agg.filter = cntd(barcode=tube_barcodes) iterator = tube_agg.iterator() while True: try: tube = iterator.next() except StopIteration: break else: self.__tube_map[tube.barcode] = tube if not len(tube_barcodes) == len(self.__tube_map): missing_tubes = [] for tube_barcode in tube_barcodes: if not self.__tube_map.has_key(tube_barcode): missing_tubes.append(tube_barcode) msg = 'Could not find tubes for the following tube barcodes: %s.' \ % (', '.join(sorted(missing_tubes))) self.add_error(msg)
def __get_pool_set(self): # Retrieves the pool set from the parsed Excel data stream. self.add_debug("Obtain pool set ...") handler = PoolCreationSetParserHandler(self.stream, parent=self) self.__pool_set = handler.get_result() parsed_num_designs = handler.get_number_designs() if parsed_num_designs != self.number_designs: msg = ( "The number of designs per molecule design pool in the " "request file (%i) differs from the requested number of " "designs (%i)." % (parsed_num_designs, self.number_designs) ) self.add_error(msg) agg = get_root_aggregate(IMoleculeType) md_type = agg.get_by_id(self.molecule_type) parsed_mol_type = handler.get_molecule_type() if parsed_mol_type != md_type: msg = ( "The molecule type of the pools in the request file (%s) " "differs from the requested molecule type (%s)." % (parsed_mol_type, self.molecule_type) ) self.add_error(msg) if self.__pool_set is None: msg = "Unable to parse library pool set!" self.add_error(msg)
def _initialize_aggregate(cls): """ Initialises the aggregate for the supported entity class (if it has not be initialised so far). """ if cls._aggregate is None: cls._aggregate = get_root_aggregate(cls._MARKER_INTERFACE)
def set_up(self): EntityTestCase.set_up(self) self._ent0 = create_entity(entity_id=0, entity_text='foo0') self._ent1 = create_entity(entity_id=1, entity_text='foo1') self._aggregate = get_root_aggregate(IMyEntity) self._aggregate.add(self._ent0) self._aggregate.add(self._ent1)
def __fetch_rack_data(self): # Fetches the racks for the rack scanning files from the database # and converts them into layouts (stored in :attr:`__db_layouts`). self.add_debug('Fetch rack data from database ...') missing_racks = [] wrong_type = [] rack_agg = get_root_aggregate(IRack) for barcode in self.__file_layouts.keys(): rack = rack_agg.get_by_slug(barcode) if rack is None: missing_racks.append(barcode) elif not isinstance(rack, TubeRack): info = '%s (%s)' % (barcode, rack.__class__.__name__) wrong_type.append(info) else: self.__racks[barcode] = rack self.__db_layouts[barcode] = RackScanningLayout.from_rack(rack) if len(missing_racks) > 0: missing_racks.sort() msg = 'Could not find database records for the following rack ' \ 'barcodes: %s.' % (', '.join(missing_racks)) self.add_error(msg) if len(wrong_type) > 0: wrong_type.sort() msg = 'The following rack are no tube racks: %s.' \ % (', '.join(wrong_type)) self.add_error(msg)
def __get_sample_stock_racks(self): """ Fetches the ISO sample stock racks and the single molecule stock racks (barcodes are found in the worklist labels). """ self.add_debug('Fetch stock racks') writer_cls = LibraryCreationWorklistWriter tube_rack_agg = get_root_aggregate(ITubeRack) not_found = [] for issr in self.stock_sample_creation_iso.iso_sector_stock_racks: self.__sample_stock_racks[issr.sector_index] = issr label = issr.planned_worklist.label starting_index = len(writer_cls.SAMPLE_STOCK_WORKLIST_LABEL) barcode_str = label[starting_index:] barcodes = barcode_str.split(writer_cls.\ SAMPLE_STOCK_WORKLIST_DELIMITER) racks = [] for barcode in barcodes: rack = tube_rack_agg.get_by_slug(barcode) if rack is None: not_found.append(barcode) else: racks.append(rack) self.__stock_rack_map[issr.sector_index] = racks if len(not_found) > 0: msg = 'The following single molecule design source stock racks ' \ 'have not been found in the DB: %s!' \ % (', '.join(sorted(not_found))) self.add_error(msg)
def __get_tube_racks(self): # Fetches the tubes rack for the rack barcodes. self.add_debug('Fetch tube racks ...') tube_rack_agg = get_root_aggregate(ITubeRack) not_found = [] for barcode in self.pool_stock_racks.values(): rack = tube_rack_agg.get_by_slug(barcode) if rack is None: not_found.append(barcode) else: self.__rack_map[barcode] = rack for barcode_list in self.tube_destination_racks.values(): for barcode in barcode_list: rack = tube_rack_agg.get_by_slug(barcode) if rack is None: not_found.append(barcode) else: self.__rack_map[barcode] = rack if len(not_found) > 0: msg = 'The following racks have not been found in the DB: %s!' \ % (', '.join(sorted(not_found))) self.add_error(msg)
def create_from_data(cls, data): if not 'lab_iso_request' in data: # We need to initialize an empty ExperimentMetadata record. rack_shapes_agg = get_root_aggregate(IRackShape) rack_shape = rack_shapes_agg.get_by_slug('8x12') experiment_design = ExperimentDesign(rack_shape=rack_shape) data['experiment_design'] = experiment_design return cls(**data) # ** pylint: disable=W0142
def _get_entity(self, icollection, key=None): agg = get_root_aggregate(icollection) if key is None: agg.slice = slice(0, 1) entity = list(agg.iterator())[0] else: entity = agg.get_by_slug(key) return entity
def opt_callback(cls, value, options): # pylint: disable=W0613 agg = get_root_aggregate(option_type) if not ',' in value: val = agg.get_by_slug(value) else: agg.filter = cntd(slug=value.split(',')) val = [ent for ent in agg] return val
def __get_tube_map_for_sector(self, layout): # We fetch all tubes for the given sector layout in one go. tube_agg = get_root_aggregate(ITube) tube_agg.filter = \ cntd(barcode=reduce(add, [pos.stock_tube_barcodes for pos in layout.get_sorted_working_positions()]) ) return (dict([(t.barcode, t) for t in iter(tube_agg)]))
def get_current_user(): """ Gets the user entity for the currently logged in user. :return: The user entity (:class:`User`). """ agg = get_root_aggregate(IUser) user_name = authenticated_userid(get_current_request()) return agg.get_by_slug(user_name)
def get_user(username): """ Gets the user entity for a given username (e.g. 'it', 'brehm' ..). :param username: The directory user name :return: The user entity (:class:`User`). """ agg = get_root_aggregate(IUser) return agg.get_by_slug(username)
def __get_molecule_design_pools(self): """ Returns the molecule design pool objects for the specified IDs. """ self.add_debug('Checks validity of the molecule design pool IDs ...') ids = self.parser.molecule_design_pool_ids agg = get_root_aggregate(IMoleculeDesignPool) agg.filter = cntd(molecule_design_set_id=ids) db_ids = set() molecule_design_pools = set() stock_concentrations = set() iterator = agg.iterator() while True: try: md_pool = iterator.next() except StopIteration: break else: if self.__molecule_type is None: self.__molecule_type = md_pool.molecule_type else: if not self.__molecule_type == md_pool.molecule_type: msg = 'There is more than one molecule type in the ' \ 'the molecule design set ("%s" and "%s")!' \ % (self.__molecule_type.name, md_pool.molecule_type.name) self.add_error(msg) return None molecule_design_pools.add(md_pool) db_ids.add(md_pool.id) stock_conc = md_pool.default_stock_concentration \ * CONCENTRATION_CONVERSION_FACTOR stock_concentrations.add(stock_conc) if not len(molecule_design_pools) == len(ids): unknown_molecule_design_pools = [] for pool_id in ids: if not pool_id in db_ids: unknown_molecule_design_pools.append(pool_id) msg = 'The following molecule design pool IDs have not be found ' \ 'in the DB: %s' % (unknown_molecule_design_pools) self.add_error(msg) if len(stock_concentrations) > 1: conc = sorted(list(stock_concentrations)) msg = 'The pools in the set have different stock concentrations: ' \ '(shown in nM): %s.' % (', '.join([str(c) for c in conc])) self.add_error(msg) else: self.__stock_concentration = list(stock_concentrations)[0] return molecule_design_pools
def reset(self): BaseParserHandler.reset(self) self.__tube_transfers = [] self.__racks = dict() self.__rack_agg = get_root_aggregate(ITubeRack) self.__timestamp = None self.__unknown_racks = [] self.__missing_tube = [] self.__mismatching_tube = [] self.__invalid_pos_label = []
def __get_empty_rack_barcode_params(self, count, tube_rack_specs_matrix): rack_agg = get_root_aggregate(ITubeRack) rack_agg.filter = eq(total_containers=0, specs=tube_rack_specs_matrix) rack_agg.slice = slice(0, count) if count == 1: params = dict(rack=str(next(rack_agg.iterator()).barcode)) else: params = dict([('rack%d' % (cnt + 1, ), str(rack.barcode)) for (cnt, rack) in enumerate(rack_agg.iterator())]) return params
def create_from_data(cls, data): # We reuse existing transfers with the same hash value. volume = data.pop('volume') hash_value = cls.get_hash_value(volume, **data) agg = get_root_aggregate(cls._MARKER_INTERFACE) pt = agg.get_by_slug(hash_value) if pt is None: pt = cls(volume=volume, hash_value=hash_value, **data) agg.add(pt) return pt
def __get_empty_rack_barcode_params(self, count, tube_rack_specs_matrix): rack_agg = get_root_aggregate(ITubeRack) rack_agg.filter = eq(total_containers=0, specs=tube_rack_specs_matrix) rack_agg.slice = slice(0, count) if count == 1: params = dict(rack=str(next(rack_agg.iterator()).barcode)) else: params = dict([('rack%d' % (cnt + 1,), str(rack.barcode)) for (cnt, rack) in enumerate(rack_agg.iterator())]) return params
def __prepare_pool_stock_rack(self, empty_rack, sector_idx): tube_specs_agg = get_root_aggregate(ITubeSpecs) ts_matrix = tube_specs_agg.get_by_slug('matrix0500') is_managed = get_item_status_managed() pos_idxs_96 = zip([1, 1, 0, 0], [1, 1, 1, 1]) (row_idx, col_idx) = pos_idxs_96[sector_idx] tube = Tube.create_from_data( dict(barcode=str(9999999990 + tube_counter.next()), status=is_managed, specs=ts_matrix)) pos = get_rack_position_from_indices(row_idx, col_idx) empty_rack.add_tube(tube, pos)
def _initialize_parser_keys(self): """ We need to set the allowed rack shapes (that is all available rack shapes) and the transfer role markers. """ self.parser.source_role_marker = TRANSFER_ROLES.SOURCE self.parser.target_role_marker = TRANSFER_ROLES.TARGET rack_shape_agg = get_root_aggregate(IRackShape) rack_shape_agg.filter = None self.parser.allowed_rack_dimensions = [(rs.number_rows, rs.number_columns) for rs in rack_shape_agg]
def test_add_update_delete(self): agg = get_root_aggregate(IUserMessage) txt = 'user message.' msg = UserMessage(txt) agg.add(msg) self.assert_is_not_none(msg.id) txt1 = 'user message 1.' msg1 = UserMessage(txt1) agg.update(msg, msg1) self.assert_equal(msg.text, txt1) agg.remove(msg) self.assert_equal(len(list(agg.iterator())), 0)
def _convert_to_rack_shape(self, rack_shape_container): """ Converts a :class:`RackShapeParsingContainer` into a :class:`thelma.entities.rack.RackShape`. """ rack_shape_aggregate = get_root_aggregate(IRackShape) rack_shape = \ rack_shape_aggregate.get_by_slug(rack_shape_container.name) if rack_shape is None: msg = 'Unable to fetch rack shape for shape label "%s"!' self.add_error(msg) return rack_shape
def create_from_data(cls, data): # We reuse molecule design sets that have the same members. agg = get_root_aggregate(cls) mds = data.pop('molecule_designs') rpr_str = MoleculeDesignPool.make_member_hash_string(mds) agg.filter = eq(member_hash=md5(rpr_str).hexdigest()) md_pools = list(agg.iterator()) if len(md_pools) == 0: # New molecule design pool. md_pool = cls(molecule_designs=mds, **data) else: md_pool, = md_pools # Must be exactly one matching pool here. return md_pool
def __get_tube_racks(self): self.add_debug('Fetching tube racks.') tube_rack_agg = get_root_aggregate(ITubeRack) query_bcs = self.single_stock_racks if not self.pool_stock_racks is None: query_bcs.extend(self.pool_stock_racks) tube_rack_agg.filter = cntd(barcode=query_bcs) rack_map = dict([(tr.barcode, tr) for tr in tube_rack_agg]) bcs_not_found = set(rack_map.keys()).symmetric_difference(query_bcs) if len(bcs_not_found) > 0: msg = 'The following racks have not been found in the DB: %s!' \ % (', '.join(sorted(bcs_not_found))) self.add_error(msg) return rack_map
def reset(self): SessionTool.reset(self) self.__tube_agg = get_root_aggregate(ITube) self.__pool_map = dict() self.__requested_tube_map = dict() self.__volume_map = dict() self.__replaced_tube_containers = [] self.__excluded_tubes = dict() self.__tube_map = dict() self.__insuffient_volume_requested = dict() self.__insuffient_volume_scheduled = dict() self.__conc_mismatch_requested = [] self.__conc_mismatch_scheduled = [] self.__missing_pools = []
def from_positions(cls, positions): """ Returns a RackPositionSet for the given positions. If there is already a set with the same hash value in the root aggregate, this set will be loaded and returned instead. """ if not isinstance(positions, set): positions = set(positions) hash_value = cls.encode_rack_position_set(positions) agg = get_root_aggregate(IRackPositionSet) rps = agg.get_by_slug(hash_value) if rps is None: rps = cls(positions=positions, hash_value=hash_value) agg.add(rps) return rps
def test_add_update_delete(self): agg = get_root_aggregate(IUserMessage) txt = 'user message.' msg = UserMessage(txt) agg.add(msg) txt1 = 'user message 1.' msg1 = UserMessage(txt1, id=msg.id) self.assert_equal(msg1.id, msg.id) msg2 = agg.update(msg1) self.assert_equal(msg2.id, msg1.id) self.assert_equal(msg2.text, txt1) msg3 = agg.get_by_id(msg.id) self.assert_equal(msg3.text, txt1) agg.remove(msg3) self.assert_equal(len(list(agg.iterator())), 0)
def __process_supplier_molecule_designs(self): self.add_debug('Processing %d new supplier molecule designs.' % len(self.__new_smd_sri_map)) smd_agg = get_root_aggregate(ISupplierMoleculeDesign) new_smds = [] for key, sris in self.__new_smd_sri_map.iteritems(): supplier, product_id = key # Create a new supplier molecule design. smd = SupplierMoleculeDesign(product_id, supplier, is_current=True) for sri in sris: # Associate the molecule designs for the sample registration # item with the new supplier molecule design. mdpri = sri.molecule_design_pool_registration_item # Associate the molecule design pool with the new supplier # molecule design. mdpri_smds = \ mdpri.molecule_design_pool.supplier_molecule_designs found_mdpri_smd = False for mdpri_smd in mdpri_smds: if mdpri_smd == smd: found_mdpri_smd = True # If this is the current supplier molecule design for # this molecule design pool, set it to "not current". if mdpri_smd.is_current: mdpri_smd.is_current = False if not found_mdpri_smd: mdpri_smds.append(smd) # *Only* for the case of a pool containing a single design, # also update the molecule design with the new supplier # molecule design. if len(mdpri.molecule_design_registration_items) == 1: mdri = mdpri.molecule_design_registration_items[0] mdri_smds = mdri.molecule_design.supplier_molecule_designs found_mdri_smd = False for mdri_smd in mdri_smds: if mdri_smd == smd: found_mdri_smd = True # If this is the current supplier molecule design for # this molecule design, set it to "not current". if mdri_smd.is_current: mdri_smd.is_current = False if not found_mdri_smd: mdri_smds.append(smd) # Update sample registration item. sri.supplier_molecule_design = smd smd_agg.add(smd) new_smds.append(smd) self.return_value['supplier_molecule_designs'] = new_smds