def compute_biomasses(self): """ Compute biomass, volume, Jenkins' biomass and wood density from equations If a tree is in it's death year, the dbh from the previous measurement is used. :Example: >>> A = Tree(cur, pcur, queries, 'NCNA000100014') >>> A.state >>> [[1979, 47.5, '1', 'G'], [1981, None, '6', 'M']] >>> A.compute_biomasses() >>> [(1.2639, 2.8725, 1.14323, 0.44), (1.2639, 2.8725, 1.14323, 0.44)] """ try: list_of_biomasses = [self.eqns[biomass_basis.maxref(x, self.species)](x) for (_,x,_,_) in self.state] list_of_basal = [round(0.00007854*float(x),3) for (_,x,_,_) in self.state] except Exception as e6: try: list_of_biomasses = [self.eqns['normal'](x) for (_,x,_,_) in self.state] list_of_basal = [round(0.00007854*float(x),3) for (_,x,_,_) in self.state] except Exception as e2: # if the final dbh is missing and the tree is dead or missing, take the final year from that missing value and give it the biomass, volume, and jenkins of the prior value if self.state[-1][1:3] == [None,'6'] or self.state[-1][1:3] == [None,'9']: final_year = self.state[-1][0] list_of_biomasses = [self.eqns[biomass_basis.maxref(x, self.species)](x) for (_,x,_,_) in self.state[:-1]] list_of_basal = [round(0.00007854*float(x),3) for (_,x,_,_) in self.state[:-1]] final_biomasses = list_of_biomasses[-1] final_basal = list_of_basal[-1] list_of_biomasses.append(final_biomasses) list_of_basal.append(final_basal) else: # new errors to debug print("error in tps_Tree.py with dealing with biomasses where DBH is None?") return list_of_biomasses, list_of_basal
def compute_biomasses(self): """ Compute biomass, volume, Jenkins' biomass and wood density from equations """ try: list_of_biomasses = [self.eqns[biomass_basis.maxref(x, self.species)](x) for (_,x,_,_) in self.state] except Exception as e: try: list_of_biomasses = [self.eqns['normal'](x) for (_,x,_,_) in self.state] except Exception as e2: # if the final dbh is missing and the tree is dead or missing, take the final year from that missing value and give it the biomass, volume, and jenkins of the prior value if self.state[-1][1:3] == [None,'6'] or self.state[-1][1:3] == [None,'9']: final_year = self.state[-1][0] list_of_biomasses = [self.eqns[biomass_basis.maxref(x, self.species)](x) for (_,x,_,_) in self.state[:-1]] final_biomasses = list_of_biomasses[-1] list_of_biomasses.append(final_biomasses) else: # new errors to debug import pdb; pdb.set_trace() return list_of_biomasses
def compute_special_biomasses(self, Xfactor): """ Compute the biomass, volume, jenkins. Use for stands with alternate minimums, areas, or detail plots First use the DetailCapture object to tell if a fancy computation (i.e. get a special area, minimum, etc. needs to be performed. Load in the appropriate parameters for this computation. Separate "small" trees from "large" ones so that small ones can get the expansion factor. If they aren't on a detail plot, this number will just be "1". :Xfactor: a DetailCapture object containing the detail plots, minimum dbhs, etc. :Xfactor.detail_reference: plots which are detail plots and when :Xfactor.stands_with_unusual_mins: plots which have minimums that are not 15 and are not detail plots :Xfactor.unusual_plot_areas: plots whose areas are not 625m """ Biomasses = {} all_years = sorted(self.shifted.keys()) for each_year in all_years: for each_species in self.shifted[each_year].keys(): if each_species == 'pimo': #import pdb; pdb.set_trace() pass for each_plot in self.shifted[each_year][each_species].keys(): # try to find the plot in the unusual mins reference try: mindbh = Xfactor.umins_reference[self.standid][each_year][each_species][each_plot] except KeyError as exc: mindbh = 15.0 # try to find the plot in the unusual areas reference try: area = Xfactor.uplot_areas[self.standid][each_year][each_species][each_plot] except KeyError as exc: area = 625. # test if the plot is a detail plot if self.standid not in Xfactor.detail_reference.keys(): Xw = 1.0 else: Xw = Xfactor.expansion[self.standid][each_year] mindbh = Xfactor.detail_reference[self.standid][each_year][each_plot]['min'] area = Xfactor.detail_reference[self.standid][each_year][each_plot]['area'] # compute the dead trees first, if the dbh is not None try: dead_trees_large = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['dead']) if value[1] != None and value[1] >= 15.0} dead_trees_small = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['dead']) if value[1] != None and value[1] >= mindbh and value[1] < 15.0} bad_dead_trees = {value[0]: {'dbh': value[1], 'status': value[2], 'year':each_year, 'plot':each_plot} for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['dead']) if value[1] == None} except Exception: flat_list = [item for sublist in self.shifted[each_year][each_species][each_plot]['dead'] for item in sublist] dead_trees_large = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(flat_list) if value[1] != None and value[1] >= 15.0} dead_trees_small = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(flat_list) if value[1] != None and value[1] >= mindbh and value[1]<15.0} bad_dead_trees = {value[0]: {'dbh': value[1], 'status': value[2], 'year':each_year, 'plot':each_plot} for index, value in enumerate(flat_list) if value[1] == None} # create a cache for the live trees for that year - remember this is in ascending order :) cached_live_trees_large = {} cached_live_trees_small = {} cached_ingrowth_trees_large = {} cached_ingrowth_trees_small = {} live_trees_large = {value[0]:{'bio' : self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['live']) if value[1]!= None and value[1] >= 15.0} live_trees_small = {value[0]:{'bio' : self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['live']) if value[1]!= None and value[1] >= mindbh and value[1] < 15.0} bad_live_trees = {value[0]: {'dbh': value[1], 'status': value[2], 'year': each_year, 'plot':each_plot } for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['live']) if value[1] == None} ingrowth_trees_large = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['ingrowth']) if value[1] != None and value[1] >= 15.0} ingrowth_trees_small = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1]), 'ba': round(0.00007854*float(value[1]),3)} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['ingrowth']) if value[1] != None and value[1] >= mindbh and value[1] < 15.0} bad_ingrowth_trees = {value[0]:{'tree': value[1] ,'status':value[2], 'year':each_year, 'plot':each_plot} for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['ingrowth']) if value[1] == None} # set the cached live trees lookup to live trees and the cached ingrowth trees lookup to ingrowth trees cached_live_trees_large = live_trees_large cached_live_trees_small = live_trees_small cached_ingrowth_trees_small = ingrowth_trees_large cached_ingrowth_trees_small = ingrowth_trees_small # if for some reason there are dead trees without a dbh, find them from the previous measurements live trees or ingrowth trees if bad_dead_trees == {}: pass elif bad_dead_trees != {}: if cached_live_trees_large != {} or cached_ingrowth_trees_large != {} or cached_live_trees_small !={} or cached_ingrowth_trees_small != {}: new_dead_trees_large = {} new_dead_trees_small = {} tids_bad_dead_trees = bad_dead_trees.keys() new_dead_trees_large = {x:cached_live_trees_large[x] for x in cached_live_trees_large.keys() if cached_live_trees_large.get(x) != None} new_dead_trees_large.update({x:cached_ingrowth_trees_large[x] for x in cached_ingrowth_trees_large.keys() if cached_ingrowth_trees_large.get(x) != None}) new_dead_trees_small.update({x:cached_ingrowth_trees_small[x] for x in cached_ingrowth_trees_small.keys() if cached_ingrowth_trees_small.get(x) != None}) new_dead_trees_small.update({x:cached_live_trees_small[x] for x in cached_live_trees_small.keys() if cached_live_trees_small.get(x) != None}) dead_trees_large.update(new_dead_trees_large) dead_trees_small.update(new_dead_trees_small) else: print(bad_dead_trees) else: pass ## All these are "normal" so we know there is not any multiplying to do and we can divide the area by 625 to get the per Mg/m2 values total_live_bio = sum([live_trees_large[tree]['bio'][0] for tree in live_trees_large.keys()])/area + sum([live_trees_small[tree]['bio'][0]*Xw for tree in live_trees_small.keys()])/area total_ingrowth_bio = sum([ingrowth_trees_large[tree]['bio'][0] for tree in ingrowth_trees_large.keys()])/area + sum([ingrowth_trees_small[tree]['bio'][0] * Xw for tree in ingrowth_trees_small.keys()])/area total_dead_bio = sum([dead_trees_large[tree]['bio'][0] for tree in dead_trees_large.keys()])/area + sum([dead_trees_small[tree]['bio'][0]*Xw for tree in dead_trees_small.keys()])/area total_live_jenkins = sum([live_trees_large[tree]['bio'][2] for tree in live_trees_large.keys()])/area + sum([live_trees_small[tree]['bio'][2] * Xw for tree in live_trees_small.keys()])/area total_ingrowth_jenkins = sum([ingrowth_trees_large[tree]['bio'][2] for tree in ingrowth_trees_large.keys()])/area + sum([ingrowth_trees_small[tree]['bio'][2] * Xw for tree in ingrowth_trees_small.keys()])/area total_dead_jenkins = sum([dead_trees_large[tree]['bio'][2] for tree in dead_trees_large.keys()])/area + sum([dead_trees_small[tree]['bio'][2] * Xw for tree in dead_trees_small.keys()])/area total_live_volume = sum([live_trees_large[tree]['bio'][1] for tree in live_trees_large.keys()])/area + sum([live_trees_small[tree]['bio'][1] * Xw for tree in live_trees_small.keys()])/area total_ingrowth_volume = sum([ingrowth_trees_large[tree]['bio'][1] for tree in ingrowth_trees_large.keys()])/area + sum([ingrowth_trees_small[tree]['bio'][1] * Xw for tree in ingrowth_trees_small.keys()])/area total_dead_volume = sum([dead_trees_large[tree]['bio'][1] for tree in dead_trees_large.keys()])/area + sum([dead_trees_small[tree]['bio'][1] * Xw for tree in dead_trees_small.keys()])/area total_live_trees = len(live_trees_large.keys())/area+ len(live_trees_small.keys())*Xw/area total_ingrowth_trees = len(ingrowth_trees_large.keys())/area + len(ingrowth_trees_small.keys())*Xw/area total_dead_trees = len(dead_trees_large.keys())/area + len(dead_trees_small.keys())*Xw/area total_live_basal = sum([live_trees_large[tree]['ba'] for tree in live_trees_large.keys()])/area + sum([live_trees_small[tree]['ba'] * Xw for tree in live_trees_small.keys()])/area total_ingrowth_basal = sum([ingrowth_trees_large[tree]['ba'] for tree in ingrowth_trees_large.keys()])/area + sum([ingrowth_trees_small[tree]['ba'] * Xw for tree in ingrowth_trees_small.keys()])/area total_dead_basal = sum([dead_trees_large[tree]['ba'] for tree in dead_trees_large.keys()])/area + sum([dead_trees_small[tree]['ba']* Xw for tree in dead_trees_small.keys()])/area # just take the wood density from one tree to have try: wooddensity_getter = list(live_trees_large)[0] wooddensity = live_trees_large[wooddensity_getter]['bio'][3] except Exception: # find the wood density by pretending that you need to compute a 25 cm tree wooddensity = self.eqns[each_species][biomass_basis.maxref(25.0, each_species)](25.0) # get a list of tree names for checking living_trees = list(live_trees_large) + list(live_trees_small) ingrowth_trees = list(ingrowth_trees_large) + list(ingrowth_trees_small) dead_trees = list(dead_trees_large) + list(dead_trees_small) if each_year not in Biomasses: Biomasses[each_year] = {each_species : {'total_live_bio': total_live_bio, 'total_dead_bio' : total_dead_bio, 'total_ingrowth_bio': total_ingrowth_bio, 'total_live_jenkins': total_live_jenkins, 'total_ingrowth_jenkins': total_ingrowth_jenkins, 'total_dead_jenkins' : total_dead_jenkins, 'total_live_volume' : total_live_volume, 'total_dead_volume' : total_dead_volume, 'total_ingrowth_volume': total_ingrowth_volume, 'total_live_trees': total_live_trees, 'total_dead_trees': total_dead_trees, 'total_ingrowth_trees': total_ingrowth_trees, 'total_live_basal': total_live_basal, 'wooddensity': wooddensity, 'name_live': living_trees, 'name_mort': dead_trees, 'total_ingrowth_basal': total_ingrowth_basal, 'total_dead_basal': total_dead_basal, 'name_ingrowth': ingrowth_trees}} elif each_year in Biomasses: # do not need to augment the wood density :) if each_species not in Biomasses[each_year]: Biomasses[each_year][each_species]={'total_live_bio': total_live_bio, 'total_dead_bio' : total_dead_bio, 'total_ingrowth_bio': total_ingrowth_bio, 'total_live_jenkins': total_live_jenkins, 'total_ingrowth_jenkins': total_ingrowth_jenkins, 'total_dead_jenkins' : total_dead_jenkins, 'total_live_volume' : total_live_volume, 'total_dead_volume' : total_dead_volume, 'total_ingrowth_volume': total_ingrowth_volume, 'total_live_trees': total_live_trees, 'total_dead_trees': total_dead_trees, 'total_ingrowth_trees': total_ingrowth_trees, 'total_live_basal': total_live_basal, 'total_dead_basal': total_dead_basal, 'name_live': living_trees, 'total_ingrowth_basal': total_ingrowth_basal, 'wooddensity': wooddensity, 'name_mort': dead_trees,'name_ingrowth': ingrowth_trees} # don't need to augment the wood density - one time is enough! elif each_species in Biomasses[each_year]: Biomasses[each_year][each_species]['total_live_bio'] += total_live_bio Biomasses[each_year][each_species]['total_dead_bio'] += total_dead_bio Biomasses[each_year][each_species]['total_ingrowth_bio'] += total_ingrowth_bio Biomasses[each_year][each_species]['total_live_jenkins'] +=total_live_jenkins Biomasses[each_year][each_species]['total_ingrowth_jenkins'] += total_ingrowth_jenkins Biomasses[each_year][each_species]['total_dead_jenkins'] += total_dead_jenkins Biomasses[each_year][each_species]['total_live_volume'] += total_live_volume Biomasses[each_year][each_species]['total_dead_volume'] += total_dead_volume Biomasses[each_year][each_species]['total_ingrowth_volume'] += total_ingrowth_volume Biomasses[each_year][each_species]['total_live_trees'] += total_live_trees Biomasses[each_year][each_species]['total_dead_trees'] += total_dead_trees Biomasses[each_year][each_species]['total_ingrowth_trees'] += total_ingrowth_trees Biomasses[each_year][each_species]['name_live'].append(living_trees) Biomasses[each_year][each_species]['name_mort'].append(dead_trees) Biomasses[each_year][each_species]['name_ingrowth'].append(ingrowth_trees) Biomasses[each_year][each_species]['total_live_basal']+=total_live_basal Biomasses[each_year][each_species]['total_dead_basal']+=total_dead_basal Biomasses[each_year][each_species]['total_ingrowth_basal']+=total_ingrowth_basal else: pass print(Biomasses) return Biomasses
def compute_normal_biomasses(self, Xfactor): """ Compute the biomass, volume, jenkins. Use for "normal" stands. First use X factor to tell if a fancy computation needs to be performed. :Xfactor: a DetailCapture object containing the detail plots, minimum dbhs, etc. :Xfactor.detail_reference: plots which are detail plots and when :Xfactor.stands_with_unusual_mins: plots which have minimums that are not 15 and are not detail plots :Xfactor.unusual_plot_areas: plots whose areas are not 625m """ Biomasses = {} if self.standid in Xfactor.detail_reference.keys() or self.standid in Xfactor.uplot_areas.keys() or self.standid in Xfactor.umins_reference.keys(): return Biomasses else: all_years = sorted(self.shifted.keys()) for each_year in all_years: for each_species in X.shifted[each_year].keys(): for each_plot in X.shifted[each_year][each_species].keys(): # compute the dead trees first, if the dbh is not None dead_trees = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1])} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['dead']) if value[1] >= 15.0 and value[1] != None} bad_dead_trees = {value[0]: {'dbh': value[1], 'status': value[2], 'year':each_year, 'plot':each_plot} for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['dead']) if value[1] == None} # create a cache for the live trees for that year - remember this is in ascending order :) cached_live_trees = {} cached_ingrowth_trees = {} live_trees = {value[0]:{'bio' : self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1])} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['live']) if value[1] >= 15.0 and value[1]!= None} bad_live_trees = {value[0]: {'dbh': value[1], 'status': value[2], 'year': each_year, 'plot':each_plot } for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['live']) if value[1] == None} ingrowth_trees = {value[0]: {'bio': self.eqns[each_species][biomass_basis.maxref(value[1], each_species)](value[1])} for index,value in enumerate(self.shifted[each_year][each_species][each_plot]['ingrowth']) if value[1] >= 15.0 and value[1] != None} bad_ingrowth_trees = {value[0]:{'tree': value[1] ,'status':value[2], 'year':each_year, 'plot':each_plot} for index, value in enumerate(self.shifted[each_year][each_species][each_plot]['ingrowth']) if value[1] == None} # set the cached live trees lookup to live trees and the cached ingrowth trees lookup to ingrowth trees cached_live_trees = live_trees cached_ingrowth_trees = ingrowth_trees # if for some reason there are dead trees without a dbh, find them from the previous measurements live trees if bad_dead_trees == {}: pass elif bad_dead_trees != {}: if cached_live_trees != {} or cached_ingrowth_trees != {}: tids_bad_dead_trees = bad_dead_trees.keys() new_dead_trees = {x:cached_live_trees[x] for x in cached_live_trees.keys() if cached_live_trees.get(x) != None} new_dead_trees.update({x:cached_ingrowth_trees[x] for x in cached_ingrowth_trees.keys() if cached_ingrowth_trees.get(x) != None}) dead_trees.update(new_dead_trees) else: badtrees.update(bad_dead_trees) else: pass ## All these are "normal" so we know there is not any multiplying to do and we can divide the area by 625 to get the per Mg/m2 values total_live_bio = sum([live_trees[tree]['bio'][0] for tree in live_trees.keys()])/625. total_ingrowth_bio = sum([ingrowth_trees[tree]['bio'][0] for tree in ingrowth_trees.keys()])/625. total_dead_bio = sum([dead_trees[tree]['bio'][0] for tree in dead_trees.keys()])/625. total_live_jenkins = sum([live_trees[tree]['bio'][2] for tree in live_trees.keys()])/625. total_ingrowth_jenkins = sum([ingrowth_trees[tree]['bio'][2] for tree in ingrowth_trees.keys()])/625. total_dead_jenkins = sum([dead_trees[tree]['bio'][2] for tree in dead_trees.keys()])/625. total_live_volume = sum([live_trees[tree]['bio'][1] for tree in live_trees.keys()])/625. total_ingrowth_volume = sum([ingrowth_trees[tree]['bio'][1] for tree in ingrowth_trees.keys()])/625. total_dead_volume = sum([dead_trees[tree]['bio'][1] for tree in dead_trees.keys()])/625. total_live_trees = len(live_trees.keys()) total_ingrowth_trees = len(ingrowth_trees.keys()) total_dead_trees = len(dead_trees.keys()) # just take the wood density from one tree to have wooddensity = live_trees[live_trees.keys()[0]]['bio'][3] # get a list of tree names for checking living_trees = live_trees.keys() ingrowth_trees = ingrowth_trees.keys() dead_trees = dead_trees.keys() if each_year not in Biomasses: Biomasses[each_year] = {each_species : {'total_live_bio': total_live_bio, 'total_dead_bio' : total_dead_bio, 'total_ingrowth_bio': total_ingrowth_bio, 'total_live_jenkins': total_live_jenkins, 'total_ingrowth_jenkins': total_ingrowth_jenkins, 'total_dead_jenkins' : total_dead_jenkins, 'total_live_volume' : total_live_volume, 'total_dead_volume' : total_dead_volume, 'total_ingrowth_volume': total_ingrowth_volume, 'total_live_trees': total_live_trees, 'total_dead_trees': total_dead_trees, 'total_ingrowth_trees': total_ingrowth_trees, 'wooddensity': wooddensity, 'num_trees': living_trees, 'num_mort': dead_trees, 'num_ingrowth': ingrowth_trees}} elif each_year in Biomasses: # do not need to augment the wood density :) if each_species not in Biomasses[each_year]: Biomasses[each_year][each_species]={'total_live_bio': total_live_bio, 'total_dead_bio' : total_dead_bio, 'total_ingrowth_bio': total_ingrowth_bio, 'total_live_jenkins': total_live_jenkins, 'total_ingrowth_jenkins': total_ingrowth_jenkins, 'total_dead_jenkins' : total_dead_jenkins, 'total_live_volume' : total_live_volume, 'total_dead_volume' : total_dead_volume, 'total_ingrowth_volume': total_ingrowth_volume, 'total_live_trees': total_live_trees, 'total_dead_trees': total_dead_trees, 'total_ingrowth_trees': total_ingrowth_trees, 'num_trees': living_trees, 'num_mort': dead_trees, 'num_ingrowth': ingrowth_trees} # don't need to augment the wood density - one time is enough! elif each_species in Biomasses[each_year]: Biomasses[each_year][each_species]['total_live_bio'] += total_live_bio Biomasses[each_year][each_species]['total_dead_bio'] += total_dead_bio Biomasses[each_year][each_species]['total_ingrowth_bio'] += total_ingrowth_bio Biomasses[each_year][each_species]['total_live_jenkins'] +=total_live_jenkins Biomasses[each_year][each_species]['total_ingrowth_jenkins'] += total_ingrowth_jenkins Biomasses[each_year][each_species]['total_dead_jenkins'] += total_dead_jenkins Biomasses[each_year][each_species]['total_live_volume'] += total_live_volume Biomasses[each_year][each_species]['total_dead_volume'] += total_dead_volume Biomasses[each_year][each_species]['total_ingrowth_volume'] += total_ingrowth_volume Biomasses[each_year][each_species]['total_live_trees'] += total_live_trees Biomasses[each_year][each_species]['total_dead_trees'] += total_dead_trees, Biomasses[each_year][each_species]['total_ingrowth_trees'] += total_ingrowth_trees Biomasses[each_year][each_species]['num_trees'] +=living_trees Biomasses[each_year][each_species]['num_mort'] += dead_trees Biomasses[each_year][each_species]['num_ingrowth'] +=ingrowth_trees else: pass print(Biomasses) return Biomasses