def test_species_diameter_and_height(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1', max_height=30, max_diameter=19) s1_gs = Species(instance=self.instance, genus='g1', species='s1', cultivar='', max_height=22, max_diameter=12) s1_gsc.save_with_system_user_bypass_auth() s1_gs.save_with_system_user_bypass_auth() row = {'point x': '16', 'point y': '20', 'genus': 'g1', 'species': 's1', 'diameter': '15', 'tree height': '18'} i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['tree height'] = 25 i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row['cultivar'] = 'c1' i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH)
def test_species_diameter_and_height(self): s1_gsc = Species( instance=self.instance, genus="g1", species="s1", cultivar="c1", max_height=30, max_diameter=19 ) s1_gs = Species(instance=self.instance, genus="g1", species="s1", cultivar="", max_height=22, max_diameter=12) s1_gsc.save_with_system_user_bypass_auth() s1_gs.save_with_system_user_bypass_auth() row = {"point x": "16", "point y": "20", "genus": "g1", "species": "s1", "diameter": "15", "tree height": "18"} i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row["tree height"] = 25 i = self.mkrow(row) i.validate_row() self.assertHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH) row["cultivar"] = "c1" i = self.mkrow(row) i.validate_row() self.assertNotHasError(i, errors.SPECIES_DBH_TOO_HIGH) self.assertNotHasError(i, errors.SPECIES_HEIGHT_TOO_HIGH)
def test_faulty_data1(self): s1_g = Species(instance=self.instance, genus="g1", species="", cultivar="", max_diameter=50.0, max_height=100.0) s1_g.save_with_system_user_bypass_auth() # TODO: READONLY restore when implemented # csv = """ # | point x | point y | diameter | read only | genus | tree height | # | -34.2 | 24.2 | q12 | true | | | # | 323 | 23.2 | 14 | falseo | | | # | 32.1 | 22.4 | 15 | true | | | # | 33.2 | 19.1 | 32 | true | | | # | 33.2 | q19.1 | -33.3 | true | gfail | | # | 32.1 | 12.1 | | false | g1 | 200 | # | 32.1 | 12.1 | 300 | false | g1 | | # """ csv = """ | point x | point y | diameter | genus | tree height | | -34.2 | 24.2 | q12 | | | | 323 | 23.2 | 14 | | | | 32.1 | 22.4 | 15 | | | | 33.2 | 19.1 | 32 | | | | 33.2 | q19.1 | -33.3 | gfail | | | 32.1 | 12.1 | | g1 | 200 | | 32.1 | 12.1 | 300 | g1 | | """ gflds = [fields.trees.POINT_X, fields.trees.POINT_Y] sflds = [ fields.trees.GENUS, fields.trees.SPECIES, fields.trees.CULTIVAR, fields.trees.OTHER_PART_OF_NAME, fields.trees.COMMON_NAME, ] j = self.run_through_process_views(csv) ierrors = self.extract_errors(j) self.assertEqual(ierrors["0"], [(errors.FLOAT_ERROR[0], [fields.trees.DIAMETER], None)]) # TODO: READONLY restore when implemented # self.assertEqual(ierrors['1'], # [(errors.BOOL_ERROR[0], # [fields.trees.READ_ONLY], None), # (errors.INVALID_GEOM[0], gflds, None)]) self.assertEqual(ierrors["1"], [(errors.INVALID_GEOM[0], gflds, None)]) self.assertNotIn("2", ierrors) self.assertNotIn("3", ierrors) self.assertEqual( ierrors["4"], [ (errors.POS_FLOAT_ERROR[0], [fields.trees.DIAMETER], None), (errors.FLOAT_ERROR[0], [fields.trees.POINT_Y], None), (errors.MISSING_FIELD[0], gflds, None), (errors.INVALID_SPECIES[0], sflds, "gfail"), ], ) self.assertEqual(ierrors["5"], [(errors.SPECIES_HEIGHT_TOO_HIGH[0], [fields.trees.TREE_HEIGHT], 100.0)]) self.assertEqual(ierrors["6"], [(errors.SPECIES_DBH_TOO_HIGH[0], [fields.trees.DIAMETER], 50.0)])
def test_faulty_data1(self): s1_g = Species(instance=self.instance, genus='g1', species='', cultivar='', max_diameter=50.0, max_height=100.0) s1_g.save_with_system_user_bypass_auth() csv = """ | point x | point y | diameter | read only | genus | tree height | | -34.2 | 24.2 | q12 | true | | | | 323 | 23.2 | 14 | falseo | | | | 32.1 | 22.4 | 15 | true | | | | 33.2 | 19.1 | 32 | true | | | | 33.2 | q19.1 | -33.3 | true | gfail | | | 32.1 | 12.1 | | false | g1 | 200 | | 32.1 | 12.1 | 300 | false | g1 | | """ gflds = [fields.trees.POINT_X, fields.trees.POINT_Y] sflds = [fields.trees.GENUS, fields.trees.SPECIES, fields.trees.CULTIVAR] j = self.run_through_process_views(csv) ierrors = self.extract_errors(j) self.assertEqual(ierrors['0'], [(errors.FLOAT_ERROR[0], [fields.trees.DIAMETER], None)]) self.assertEqual(ierrors['1'], [(errors.BOOL_ERROR[0], [fields.trees.READ_ONLY], None), (errors.INVALID_GEOM[0], gflds, None)]) self.assertNotIn('2', ierrors) self.assertNotIn('3', ierrors) self.assertEqual(ierrors['4'], [(errors.POS_FLOAT_ERROR[0], [fields.trees.DIAMETER], None), (errors.FLOAT_ERROR[0], [fields.trees.POINT_Y], None), (errors.MISSING_FIELD[0], gflds, None), (errors.INVALID_SPECIES[0], sflds, 'gfail')]) self.assertEqual(ierrors['5'], [(errors.SPECIES_HEIGHT_TOO_HIGH[0], [fields.trees.TREE_HEIGHT], 100.0)]) self.assertEqual(ierrors['6'], [(errors.SPECIES_DBH_TOO_HIGH[0], [fields.trees.DIAMETER], 50.0)])
def test_common_name_matching(self): apple = Species(instance=self.instance, genus='malus', common_name='Apple') apple.save_with_system_user_bypass_auth() csv = """ | point x | point y | genus | common name | | 45.59 | 31.1 | malus | apple | | 45.58 | 33.9 | malus | crab apple | | 45.58 | 33.9 | malus | | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) rows = ie.treeimportrow_set.order_by('idx').all() tree1 = rows[0].plot.current_tree() tree3 = rows[2].plot.current_tree() self.assertEqual(tree1.species.pk, apple.pk) self.assertIsNone(rows[1].plot) self.assertEqual(tree3.species.pk, apple.pk) # If we add a species, there will be more than one match for "malus" csv = """ | point x | point y | genus | common name | | 45.49 | 31.1 | malus | apple | | 45.48 | 33.9 | malus | crab apple | | 45.48 | 33.9 | malus | | """ crab_apple = Species(instance=self.instance, genus='malus', common_name='Crab Apple') crab_apple.save_with_system_user_bypass_auth() ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) rows = ie.treeimportrow_set.order_by('idx').all() tree1 = rows[0].plot.current_tree() tree2 = rows[1].plot.current_tree() self.assertEqual(tree1.species.pk, apple.pk) self.assertEqual(tree2.species.pk, crab_apple.pk) self.assertIsNone(rows[2].plot)
def test_all_tree_data(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1') s1_gsc.save_with_system_user_bypass_auth() csv = """ | point x | point y | diameter | tree height | | 45.53 | 31.1 | 23.1 | 90.1 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) tree = ie.treeimportrow_set.all()[0].plot.current_tree() self.assertEqual(tree.diameter, 23.1) self.assertEqual(tree.height, 90.1) csv = """ | point x | point y | canopy height | genus | species | cultivar | | 45.59 | 31.1 | 112 | | | | | 45.58 | 33.9 | | g1 | s1 | c1 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) rows = ie.treeimportrow_set.order_by('idx').all() tree1 = rows[0].plot.current_tree() tree2 = rows[1].plot.current_tree() self.assertEqual(tree1.canopy_height, 112) self.assertIsNone(tree1.species) self.assertEqual(tree2.species.pk, s1_gsc.pk) # TODO: READONLY restore when implemented # csv = """ # | point x | point y | date planted | read only | # | 25.00 | 25.00 | 2012-02-03 | true | # """ csv = """ | point x | point y | date planted | | 25.00 | 25.00 | 2012-02-03 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) tree = ie.treeimportrow_set.all()[0].plot.current_tree() dateplanted = date(2012, 2, 3) self.assertEqual(tree.date_planted, dateplanted) # TODO: READONLY restore when implemented # self.assertEqual(tree.readonly, True) psycopg2.extras.register_hstore(connection.cursor(), globally=True) UserDefinedFieldDefinition.objects.create( model_type='Plot', name='Flatness', datatype=json.dumps({'type': 'choice', 'choices': ['very', 'hardly', 'not']}), iscollection=False, instance=self.instance, ) UserDefinedFieldDefinition.objects.create( model_type='Tree', name='Cuteness', datatype=json.dumps({'type': 'choice', 'choices': ['lots', 'not much', 'none']}), iscollection=False, instance=self.instance, ) csv = """ | point x | point y | tree: cuteness | plot: flatness | | 26.00 | 26.00 | not much | very | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) plot = ie.treeimportrow_set.all()[0].plot tree = plot.current_tree() self.assertEqual(plot.udfs['Flatness'], 'very') self.assertEqual(tree.udfs['Cuteness'], 'not much')
def commit_row(self): is_valid = self.validate_row() if not is_valid or not self.merged: return # not ready to commit if self.status == SpeciesImportRow.SUCCESS: return # nothing changed so no need to commit # Get our data data = self.cleaned species_edited = False # Initially grab species from row if it exists and edit it species = self.species # If not specified create a new one if species is None: species = Species(instance=self.import_event.instance) # Convert units self.convert_units(data, { fields.species.MAX_DIAMETER: self.import_event.max_diameter_conversion_factor, fields.species.MAX_HEIGHT: self.import_event.max_tree_height_conversion_factor }) for modelkey, datakey in SpeciesImportRow.SPECIES_MAP.iteritems(): importdata = data.get(datakey, None) if importdata is not None: species_edited = True setattr(species, modelkey, importdata) # Set OTM code if missing and available if not species.otm_code: species_dict = species_for_scientific_name( species.genus, species.species, species.cultivar, species.other_part_of_name) if species_dict: species_edited = True species.otm_code = species_dict['otm_code'] if species_edited: species.save_with_system_user_bypass_auth() # Make i-Tree code override(s) if necessary if fields.species.ITREE_PAIRS in data: for region_code, itree_code in data[fields.species.ITREE_PAIRS]: if itree_code != species.get_itree_code(region_code): override = ITreeCodeOverride.objects.get_or_create( instance_species=species, region=ITreeRegion.objects.get(code=region_code), )[0] override.itree_code = itree_code override.save_with_user(User.system_user()) self.species = species self.status = SpeciesImportRow.SUCCESS self.save()
def test_all_tree_data(self): s1_gsc = Species(instance=self.instance, genus='g1', species='s1', cultivar='c1') s1_gsc.save_with_system_user_bypass_auth() csv = """ | point x | point y | diameter | tree height | | 45.53 | 31.1 | 23.1 | 90.1 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) tree = ie.treeimportrow_set.all()[0].plot.current_tree() self.assertEqual(tree.diameter, 23.1) self.assertEqual(tree.height, 90.1) csv = """ | point x | point y | canopy height | genus | species | cultivar | | 45.59 | 31.1 | 112 | | | | | 45.58 | 33.9 | | g1 | s1 | c1 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) rows = ie.treeimportrow_set.order_by('idx').all() tree1 = rows[0].plot.current_tree() tree2 = rows[1].plot.current_tree() self.assertEqual(tree1.canopy_height, 112) self.assertIsNone(tree1.species) self.assertEqual(tree2.species.pk, s1_gsc.pk) # TODO: READONLY restore when implemented # csv = """ # | point x | point y | date planted | read only | # | 25.00 | 25.00 | 2012-02-03 | true | # """ csv = """ | point x | point y | date planted | | 25.00 | 25.00 | 2012-02-03 | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) tree = ie.treeimportrow_set.all()[0].plot.current_tree() dateplanted = date(2012, 2, 3) self.assertEqual(tree.date_planted, dateplanted) # TODO: READONLY restore when implemented # self.assertEqual(tree.readonly, True) psycopg2.extras.register_hstore(connection.cursor(), globally=True) UserDefinedFieldDefinition.objects.create( model_type='Plot', name='Flatness', datatype=json.dumps({ 'type': 'choice', 'choices': ['very', 'hardly', 'not'] }), iscollection=False, instance=self.instance, ) UserDefinedFieldDefinition.objects.create( model_type='Tree', name='Cuteness', datatype=json.dumps({ 'type': 'choice', 'choices': ['lots', 'not much', 'none'] }), iscollection=False, instance=self.instance, ) csv = """ | point x | point y | tree: cuteness | plot: flatness | | 26.00 | 26.00 | not much | very | """ ieid = self.run_through_commit_views(csv) ie = TreeImportEvent.objects.get(pk=ieid) plot = ie.treeimportrow_set.all()[0].plot tree = plot.current_tree() self.assertEqual(plot.udfs['Flatness'], 'very') self.assertEqual(tree.udfs['Cuteness'], 'not much')
def test_faulty_data1(self): s1_g = Species(instance=self.instance, genus='g1', species='', cultivar='', max_diameter=50.0, max_height=100.0) s1_g.save_with_system_user_bypass_auth() # TODO: READONLY restore when implemented # csv = """ # | point x | point y | diameter | read only | genus | tree height | # | -34.2 | 24.2 | q12 | true | | | # | 323 | 23.2 | 14 | falseo | | | # | 32.1 | 22.4 | 15 | true | | | # | 33.2 | 19.1 | 32 | true | | | # | 33.2 | q19.1 | -33.3 | true | gfail | | # | 32.1 | 12.1 | | false | g1 | 200 | # | 32.1 | 12.1 | 300 | false | g1 | | # """ csv = """ | point x | point y | diameter | genus | tree height | | -34.2 | 24.2 | q12 | | | | 323 | 23.2 | 14 | | | | 32.1 | 22.4 | 15 | | | | 33.2 | 19.1 | 32 | | | | 33.2 | q19.1 | -33.3 | gfail | | | 32.1 | 12.1 | | g1 | 200 | | 32.1 | 12.1 | 300 | g1 | | """ gflds = [fields.trees.POINT_X, fields.trees.POINT_Y] sflds = [ fields.trees.GENUS, fields.trees.SPECIES, fields.trees.CULTIVAR, fields.trees.OTHER_PART_OF_NAME, fields.trees.COMMON_NAME ] j = self.run_through_process_views(csv) ierrors = self.extract_errors(j) self.assertEqual( ierrors['0'], [(errors.FLOAT_ERROR[0], [fields.trees.DIAMETER], None)]) # TODO: READONLY restore when implemented # self.assertEqual(ierrors['1'], # [(errors.BOOL_ERROR[0], # [fields.trees.READ_ONLY], None), # (errors.INVALID_GEOM[0], gflds, None)]) self.assertEqual(ierrors['1'], [(errors.INVALID_GEOM[0], gflds, None)]) self.assertNotIn('2', ierrors) self.assertNotIn('3', ierrors) self.assertEqual( ierrors['4'], [(errors.POS_FLOAT_ERROR[0], [fields.trees.DIAMETER], None), (errors.FLOAT_ERROR[0], [fields.trees.POINT_Y], None), (errors.MISSING_FIELD[0], gflds, None), (errors.INVALID_SPECIES[0], sflds, 'gfail')]) self.assertEqual(ierrors['5'], [(errors.SPECIES_HEIGHT_TOO_HIGH[0], [fields.trees.TREE_HEIGHT], 100.0)]) self.assertEqual( ierrors['6'], [(errors.SPECIES_DBH_TOO_HIGH[0], [fields.trees.DIAMETER], 50.0)])
def commit_row(self): is_valid = self.validate_row() if not is_valid or not self.merged: return # not ready to commit if self.status == SpeciesImportRow.SUCCESS: return # nothing changed so no need to commit # Get our data data = self.cleaned species_edited = False # Initially grab species from row if it exists and edit it species = self.species # If not specified create a new one if species is None: species = Species(instance=self.import_event.instance) # Convert units self.convert_units( data, { fields.species.MAX_DIAMETER: self.import_event.max_diameter_conversion_factor, fields.species.MAX_HEIGHT: self.import_event.max_tree_height_conversion_factor }) for modelkey, datakey in SpeciesImportRow.SPECIES_MAP.iteritems(): importdata = data.get(datakey, None) if importdata is not None: species_edited = True setattr(species, modelkey, importdata) # Set OTM code if missing and available if not species.otm_code: species_dict = species_for_scientific_name( species.genus, species.species, species.cultivar, species.other_part_of_name) if species_dict: species_edited = True species.otm_code = species_dict['otm_code'] if species_edited: species.save_with_system_user_bypass_auth() # Make i-Tree code override(s) if necessary if fields.species.ITREE_PAIRS in data: for region_code, itree_code in data[fields.species.ITREE_PAIRS]: if itree_code != species.get_itree_code(region_code): override = ITreeCodeOverride.objects.get_or_create( instance_species=species, region=ITreeRegion.objects.get(code=region_code), )[0] override.itree_code = itree_code override.save_with_user(User.system_user()) self.species = species self.status = SpeciesImportRow.SUCCESS self.save()