def calculate_properties descriptors=PhysChem::OPENBABEL
      calculated_ids = properties.keys
      # BSON::ObjectId instances are not allowed as keys in a BSON document.
      new_ids = descriptors.collect{|d| d.id.to_s} - calculated_ids
      descs = {}
      algos = {}
      new_ids.each do |id|
        descriptor = PhysChem.find id
        descs[[descriptor.library, descriptor.descriptor]]  = descriptor
        algos[descriptor.name] = descriptor
      end
      # avoid recalculating Cdk features with multiple values
      descs.keys.uniq.each do |k|
        descs[k].send(k[0].downcase,k[1],self).each do |n,v|
          properties[algos[n].id.to_s] = v # BSON::ObjectId instances are not allowed as keys in a BSON document.
        end
      end
      save
      descriptors.collect{|d| properties[d.id.to_s]}
    end
def calculate_properties descriptors=PhysChem::OPENBABEL
      calculated_ids = properties.keys
      # BSON::ObjectId instances are not allowed as keys in a BSON document.
      new_ids = descriptors.collect{|d| d.id.to_s} - calculated_ids
      descs = {}
      algos = {}
      new_ids.each do |id|
        descriptor = PhysChem.find id
        descs[[descriptor.library, descriptor.descriptor]]  = descriptor
        algos[descriptor.name] = descriptor
      end
      # avoid recalculating Cdk features with multiple values
      descs.keys.uniq.each do |k|
        descs[k].send(k[0].downcase,k[1],self).each do |n,v|
          properties[algos[n].id.to_s] = v # BSON::ObjectId instances are not allowed as keys in a BSON document.
        end
      end
      save
      descriptors.collect{|d| properties[d.id.to_s]}
    end
Calculate physchem properties
 @param [Array<Hash>] list of descriptors
 @return [Array<Float>]