def test_modeling_ar119(self): ''' AR-119: Get Rid of Bidding Model ''' output = self.run_pipeline('ar119') activities = output['model-activity'] self.assertNotIn('model-bidding', output) offer1 = activities['tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,Br-4537,1836-01-30,0035'] assignments1 = [p for p in offer1.get('part', []) if p['type'] == 'AttributeAssignment'] self.assertEqual(len(assignments1), 1) assignment1 = assignments1[0] self.assertEqual(assignment1['_label'], 'Bidding valuation of Br-4537 0035 1836-01-30') self.assertEqual(classification_sets(assignment1), {'Bidding'}) amounts1 = assignment1['assigned'] self.assertEqual(len(amounts1), 1) amount1 = amounts1[0] self.assertEqual(amount1['_label'], '3.50 pounds') buyers1 = assignment1.get('carried_out_by', []) self.assertEqual(len(buyers1), 0) # bought-in, so no buyer data offer2 = activities['tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,Br-4536,1836-01-29,0008'] assignments2 = [p for p in offer2.get('part', []) if p['type'] == 'AttributeAssignment'] self.assertEqual(len(assignments2), 1) assignment2 = assignments2[0] self.assertEqual(assignment2['_label'], 'Bidding valuation of Br-4536 0008 1836-01-29') self.assertEqual(classification_sets(assignment2), {'Bidding'}) amounts2 = assignment2['assigned'] self.assertEqual(len(amounts2), 1) amount2 = amounts2[0] self.assertEqual(amount2['_label'], '0.14 pounds') buyers2 = assignment2.get('carried_out_by', []) self.assertEqual(len(buyers2), 1) buyer2 = buyers2[0] self.assertEqual(buyer2['_label'], 'Balmer')
def verifyAgents(self, tx, sellers, seller_agents, buyer_agents, buyers): acqs = [p for p in tx['part'] if p.get('type') == 'Acquisition'] self.assertEqual(len(acqs), 1) acq = acqs[0] reciever = {p.get('_label') for p in acq['transferred_title_from']} sender = {p.get('_label') for p in acq['transferred_title_to']} self.assertEqual(sender, buyers) self.assertEqual(reciever, sellers) seller_agent_parts = [ p for p in acq.get('part', []) if "Seller's Agent" in classification_sets(p) ] buyer_agent_parts = [ p for p in acq.get('part', []) if "Buyer's Agent" in classification_sets(p) ] actual_seller_agents = set([ p['_label'] for part in seller_agent_parts for p in part.get('carried_out_by', []) ]) actual_buyer_agents = set([ p['_label'] for part in buyer_agent_parts for p in part.get('carried_out_by', []) ]) self.assertEqual(actual_seller_agents, seller_agents) self.assertEqual(actual_buyer_agents, buyer_agents)
def test_modeling_ar120(self): ''' AR-120: Add bid records when no price indicated in a sales record. ''' output = self.run_pipeline('ar120') texts = output['model-lo'] activities = output['model-activity'] prov1 = activities['tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,B-A15,1739-07-20,0233'] assignments1 = [p for p in prov1.get('part', []) if p['type'] == 'AttributeAssignment'] self.assertEqual(len(assignments1), 1) assignment1 = assignments1[0] self.assertEqual(assignment1['_label'], 'Bidding valuation of B-A15 0233 1739-07-20') self.assertEqual(classification_sets(assignment1), {'Bidding'}) self.assertNotIn('assigned', assignment1) buyers1 = assignment1.get('carried_out_by', []) self.assertEqual(len(buyers1), 1) # bought-in, so no buyer data buyer1 = buyers1[0] self.assertEqual(buyer1['_label'], 'Servees') prov2 = activities['tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,Br-A1875,1792-02-18,0008'] assignments2 = [p for p in prov2.get('part', []) if p['type'] == 'AttributeAssignment'] self.assertEqual(len(assignments2), 1) assignment2 = assignments2[0] self.assertEqual(assignment2['_label'], 'Bidding valuation of Br-A1875 0008 1792-02-18') self.assertEqual(classification_sets(assignment2), {'Bidding'}) self.assertNotIn('assigned', assignment2) buyers2 = assignment2.get('carried_out_by', []) self.assertEqual(len(buyers2), 1) # bought-in, so no buyer data buyer2 = buyers2[0] self.assertEqual(buyer2['_label'], 'Skirrow')
def test_modeling_ar123(self): ''' AR-123: Record winning bid for Sold records ''' output = self.run_pipeline('ar123') texts = output['model-lo'] activities = output['model-activity'] prov1 = activities[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,B-267,1817,0001'] assignments1 = [ p for p in prov1.get('part', []) if p['type'] == 'AttributeAssignment' ] self.assertEqual(len(assignments1), 1) assignment1 = assignments1[0] self.assertEqual(assignment1['_label'], 'Bidding valuation of B-267 0001 1817') self.assertEqual(classification_sets(assignment1), {'Bidding'}) amounts1 = assignment1['assigned'] self.assertEqual(len(amounts1), 1) amount1 = amounts1[0] self.assertEqual(amount1['_label'], '50,000.00 frs') self.assertEqual(classification_sets(amount1), {'Sale Price'}) buyers1 = assignment1.get('carried_out_by', []) self.assertEqual(len(buyers1), 1) buyer1 = buyers1[0] self.assertEqual(buyer1['_label'], "Stier d'Aertselaer, Henri-Joseph, baron") prov2 = activities[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,B-3,1801-03-26,0045'] assignments2 = [ p for p in prov2.get('part', []) if p['type'] == 'AttributeAssignment' ] self.assertEqual(len(assignments2), 1) assignment2 = assignments2[0] self.assertEqual(assignment2['_label'], 'Bidding valuation of B-3 0045 1801-03-26') self.assertEqual(classification_sets(assignment2), {'Bidding'}) amounts2 = assignment2['assigned'] self.assertEqual(len(amounts2), 1) amount2 = amounts2[0] self.assertEqual(amount2['_label'], '0.10') self.assertEqual(classification_sets(amount2), {'Hammer Price'}) buyers2 = assignment2.get('carried_out_by', []) self.assertEqual(len(buyers2), 1) buyer2 = buyers2[0] self.assertEqual(buyer2['_label'], 'Schell (Gent)')
def test_modeling_ar102(self): ''' AR-102: Add form types to textual work records ''' output = self.run_pipeline('ar102') texts = output['model-lo'] book = texts[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,5'] page = texts[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,5,Page,190'] entry = texts[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,5,Page,190,Row,38'] self.assertEqual( classification_sets(book, key='id'), { 'http://vocab.getty.edu/aat/300028051', 'http://vocab.getty.edu/aat/300027483' }) self.assertEqual(classification_sets(page, key='id'), {'http://vocab.getty.edu/aat/300194222'}) self.assertEqual(classification_sets(entry, key='id'), {'http://vocab.getty.edu/aat/300438434'}) self.assertEqual( classification_tree(book, key='id'), { 'http://vocab.getty.edu/aat/300027483': { 'http://vocab.getty.edu/aat/300435443': {} }, # Account Book => Type of Work 'http://vocab.getty.edu/aat/300028051': { 'http://vocab.getty.edu/aat/300444970': {} } # Book => Form }) self.assertEqual( classification_tree(page, key='id'), { 'http://vocab.getty.edu/aat/300194222': { 'http://vocab.getty.edu/aat/300444970': {} } # Page => Form }) self.assertEqual( classification_tree(entry, key='id'), { 'http://vocab.getty.edu/aat/300438434': { 'http://vocab.getty.edu/aat/300444970': {} } # Entry => Form })
def test_modeling_ar86(self): ''' AR-86: Improve modeling of unsold purchases and inventorying ''' output = self.run_pipeline('ar86') activities = output['model-activity'] # There are three entries for this object (with transaction types "unsold", "unsold", and "sold"). # From these entries, we should see: # - 1 purchase event ("unsold" but with seller information) # - 2 inventorying event ("unsold" but no seller information, and also "sold" with no seller information) # - 1 sale event ("sold") k_purchases = [a for a in activities.values() if a.get('_label', '').startswith('Knoedler Purchase of Stock Number 5323')] self.assertEqual(len(k_purchases), 1) k_inventorying = [a for a in activities.values() if a.get('_label', '').startswith('Knoedler Inventorying of Stock Number 5323')] self.assertEqual(len(k_inventorying), 2) k_sales = [a for a in activities.values() if a.get('_label', '').startswith('Knoedler Sale of Stock Number 5323')] self.assertEqual(len(k_sales), 1) # Also, the two inventorying events should have price information representing Knoedler's evaluated worth of the object # In this case, both inventorying activities resulted in the same evaluated amount (1250 francs). for act in k_inventorying: assignments = [a for a in act.get('part', []) if a.get('_label', '').startswith('Evaluated worth of Stock Number 5323')] self.assertEqual(len(assignments), 1) assignment = assignments[0] self.assertTrue(assignment['_label'].startswith('Evaluated worth of Stock Number 5323')) self.assertEqual(assignment['assigned_property'], 'dimension') self.assertEqual(assignment['assigned'][0]['_label'], '1,250.00 francs') self.assertEqual(assignment['assigned_to']['_label'], '[Language of fair title info from Sales Book 7, 1892-1900, f.36]') self.assertEqual(classification_sets(assignment['assigned'][0]), {'Valuation'})
def verifyAttributedToObject(self, hmo, name, classifications=None): prod = hmo['produced_by'] self.assertIn('attributed_by', prod) attrs = [a for a in prod['attributed_by'] if a.get('assigned_property') == 'carried_out_by'] self.assertEqual(len(attrs), 1) attr = attrs[0] # the next two assertions capture the case of 'Possibly by XXX' and 'Possibly attributed to XXX' self.assertTrue(attr['_label'].startswith(f'Possibly')) self.assertTrue(attr['_label'].endswith(name)) self.assertIn('assigned', attr) people = attr['assigned'] self.assertEqual(len(people), 1) person = people[0] self.assertEqual(person['_label'], name) if classifications: self.assertEqual(classification_sets(attr), classifications)
def test_modeling_ar121(self): ''' AR-121: Populate the Subject Field of Textual Work ''' output = self.run_pipeline('ar121') texts = output['model-lo'] expected = { 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,D-A92,RECORD,936865': 'Bought In', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,B-A111,RECORD,12666': 'Bought In', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,B-A13,RECORD,7215': 'Withdrawn', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,B-A136,RECORD,1': None, 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,B-A138,RECORD,138': 'Purchase', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,Br-4716,RECORD,105972': None, 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,D-A63,RECORD,935519': None, 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,D-A63,RECORD,935520': 'Purchase', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,D-A92,RECORD,936865': 'Bought In', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,D-A96,RECORD,937738': 'Withdrawn', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,F-A1045,RECORD,716405': 'Bought In', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,F-A12,RECORD,716158': 'Withdrawn', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,F-A458,RECORD,715256': None, 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#CATALOG,F-A458,RECORD,715265': 'Purchase' } for url, cl in expected.items(): record = texts[url] got = classification_sets(record, classification_key='about') self.assertIn(cl, got)
def test_modeling_ar121(self): ''' AR-121: Populate the Subject Field of Textual Work ''' output = self.run_pipeline('ar121') texts = output['model-lo'] expected = { 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,2,Page,222,Row,15': 'Lost', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,3,Page,11,Row,20': 'Inventorying', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,3,Page,13,Row,1': 'Returning', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,3,Page,78,Row,21': 'Gift', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,4,Page,197,Row,18': 'Exchange', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,4,Page,29,Row,14': 'Purchase', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,8,Page,215,Row,17': 'Destroyed', 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:knoedler#Text,Book,9,Page,33,Row,13': 'Stolen' } for url, cl in expected.items(): record = texts[url] got = classification_sets(record, classification_key='about') self.assertIn(cl, got)
def verify_sales(self, output): ''' For a private contract sale record, there should be: * A private sale activity classified as an Exhibition * An Object Set classified as a Collection, having an Asking Price * A HumanMadeObject classified as a Painting, and belonging to the Object Set * A Provenance Entry for the private sale, including: * An Acquisition with transfer of title from the Seller to the Buyer * A Transfer of Custody from the Seller to the Sale Organizer * A Transfer of Custody from the Sale Organizer to the Buyer * A Provenance Entry for the seller's previous ownership, including: * An Acquisition with transfer of title to the Seller * A Transfer of Custody to the Seller ''' objects = output['model-object'] activities = output['model-activity'] sale_activities = output['model-sale-activity'] sets = output['model-set'] texts = output['model-lo'] hmo_key = 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#OBJ,B-267,0001,1817' hmo = objects[hmo_key] prov_entry_curr = activities[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,B-267,1817,0001'] prov_entry_prev = activities[ 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PROV,Seller-0,OBJ,B-267,0001,1817'] event_key = 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#PRIVATE_CONTRACT_SALE-EVENT,B-267' sale_event = sale_activities[event_key] object_set_key = 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#AUCTION,B-267,0001,1817-Set' object_set = sets[object_set_key] self.assertEqual({c['_label'] for c in sale_event['classified_as']}, {'Exhibiting'}) self.assertEqual({c['_label'] for c in object_set['classified_as']}, {'Collection'}) assignments1 = [ p for p in prov_entry_curr.get('part', []) if p['type'] == 'AttributeAssignment' ] self.assertEqual(len(assignments1), 1) assignment1 = assignments1[0] self.assertEqual(assignment1['_label'], 'Bidding valuation of B-267 0001 1817') self.assertEqual(classification_sets(assignment1), {'Bidding'}) prices = assignment1['assigned'] self.assertEqual(len(prices), 1) amount1 = prices[0] self.assertEqual(amount1['_label'], '50,000.00 frs') self.assertEqual(classification_sets(amount1), {'Sale Price'}) self.assertEqual(len(prices), 1) self.assertEqual({c['_label'] for c in prices[0]['classified_as']}, {'Sale Price'}) self.assertEqual(prices[0]['_label'], "50,000.00 frs") self.assertEqual(prices[0]['currency']['_label'], 'French Francs') self.assertEqual(prices[0]['value'], 50000) self.assertIn(object_set_key, {s['id'] for s in hmo['member_of']}) self.assertEqual(sorted( [p['type'] for p in prov_entry_curr['part']]), [ 'Acquisition', 'AttributeAssignment', 'Payment', 'Payment', 'TransferOfCustody', 'TransferOfCustody' ]) acq = [ p for p in prov_entry_curr['part'] if p['type'] == 'Acquisition' ][0] xfers = [ p for p in prov_entry_curr['part'] if p['type'] == 'TransferOfCustody' ] # seller : Havre, Jean-Michel-Antoine-Joseph-Louis, baron van 500439105 # buyer : Stier d'Aertselaer, Henri-Joseph, baron 500440144 # organizer: Anonymous 22949 event_organizer = 'tag:getty.edu,2019:digital:pipeline:REPLACE-WITH-UUID:sales#HOUSE,STAR,226,0' # TODO this should be pulled from the data buyers = acq['transferred_title_to'] self.assertEqual(len(buyers), 1) buyer = buyers[0]['id'] sellers = acq['transferred_title_from'] self.assertEqual(len(sellers), 1) seller = sellers[0]['id'] acq_objects = acq['transferred_title_of'] self.assertEqual(len(acq_objects), 1) self.assertEqual(acq_objects[0]['id'], hmo['id']) for xfer in xfers: xfer_objects = xfer['transferred_custody_of'] self.assertEqual(len(xfer_objects), 1) self.assertEqual(xfer_objects[0]['id'], hmo['id']) xfer_pairs = {(xfer['transferred_custody_from'][0]['id'], xfer['transferred_custody_to'][0]['id']) for xfer in xfers} expected_pairs = {(seller, event_organizer), (event_organizer, buyer)} self.assertEqual(xfer_pairs, expected_pairs) self.assertEqual(sorted([p['type'] for p in prov_entry_prev['part']]), ['Acquisition', 'TransferOfCustody']) prev_acq = [ p for p in prov_entry_prev['part'] if p['type'] == 'Acquisition' ][0] prev_xfers = [ p for p in prov_entry_prev['part'] if p['type'] == 'TransferOfCustody' ] prev_buyers = prev_acq['transferred_title_to'] self.assertEqual(len(prev_buyers), 1) prev_buyer = prev_buyers[0]['id'] self.assertEqual(prev_buyer, seller) self.assertEqual(len(prev_xfers), 1) for xfer in prev_xfers: xfer_objects = xfer['transferred_custody_of'] self.assertEqual(len(xfer_objects), 1) self.assertEqual(xfer_objects[0]['id'], hmo['id']) prev_xfer = prev_xfers[0] self.assertEqual( {p['id'] for p in prev_xfer['transferred_custody_to']}, {seller})