PageRenderTime 34ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/rcdk/R/formula.R

http://github.com/rajarshi/cdkr
R | 575 lines | 326 code | 77 blank | 172 comment | 63 complexity | 414dee67dd6cc7a0b768ee0dbf67a145 MD5 | raw file
  1. ########################################################
  2. ## set a cdkFormula function
  3. .IMolecularFormula <- "org/openscience/cdk/interfaces/IMolecularFormula"
  4. #' @name cdkFormula-class
  5. #' @title Class cdkFormula, ac class for handling molecular formula
  6. #' @description This class handles molecular formulae. It provides extra
  7. #' information such as the IMolecularFormula Java object, elements contained
  8. #' and number of them.
  9. #' @section Objects from the Class:
  10. #' Objects can be created using new constructor and filled with a specific
  11. #' mass and window accuracy
  12. #' @author Miguel Rojas-Cherto (\email{miguelrojasch@@yahoo.es})
  13. #' @references A parallel effort to expand the Chemistry Development
  14. #' Kit: \url{http://cdk.sourceforge.net}
  15. #' @seealso
  16. #' \code{\link{get.formula}}
  17. #' \code{\link{set.charge.formula}}
  18. #' \code{\link{get.isotopes.pattern}}
  19. #' \code{\link{isvalid.formula}}
  20. #' @docType class
  21. #' @aliases cdkFormula-class
  22. #' @aliases show,cdkFormula-method
  23. setClass("cdkFormula", representation(mass = "numeric",
  24. objectJ = "jobjRef",
  25. string = "character",
  26. charge = "numeric",
  27. isotopes = "matrix"),
  28. prototype(mass = 0,
  29. objectJ = NULL,
  30. string = character(0),
  31. charge = 0,
  32. isotopes = matrix(nrow = 0, ncol = 0))
  33. )
  34. #' get.formula
  35. #'
  36. #' obtain molecular formula from formula string
  37. #'
  38. #' @param mf Required. Molecular formula
  39. #' @param charge Optional. Default \code{0}
  40. #' @export
  41. get.formula <- function(mf, charge=0) {
  42. manipulator <- get("mfManipulator", envir = .rcdk.GlobalEnv)
  43. if(!is.character(mf)) {
  44. stop("Must supply a Formula string");
  45. }else{
  46. dcob <- .cdkFormula.createChemObject()
  47. molecularformula <- .cdkFormula.createFormulaObject()
  48. molecularFormula <- .jcall(manipulator,
  49. "Lorg/openscience/cdk/interfaces/IMolecularFormula;",
  50. "getMolecularFormula",
  51. mf,
  52. .jcast(molecularformula,.IMolecularFormula),
  53. TRUE);
  54. }
  55. D <- new(J("java/lang/Integer"), as.integer(charge))
  56. .jcall(molecularFormula,"V","setCharge",D);
  57. object <- .cdkFormula.createObject(.jcast(molecularFormula,.IMolecularFormula));
  58. return(object);
  59. }
  60. setMethod("show", "cdkFormula",
  61. function(object) {
  62. cat('cdkFormula: ',object@string,
  63. ', mass = ',object@mass, ', charge = ',
  64. object@charge, '\n')
  65. })
  66. #'
  67. #' get.mol2formula
  68. #'
  69. #'
  70. #' @param molecule The molecule to query. Should be a `jobjRef` representing an `IAtomContainer`
  71. #' @param charge Optional. Default \code{0}
  72. #' @export
  73. get.mol2formula <- function(molecule, charge=0) {
  74. if(attr(molecule, "jclass") != "org/openscience/cdk/interfaces/IAtomContainer") {
  75. stop("Must supply an IAtomContainerobject")
  76. }
  77. formulaJ <- .jcall('org/openscience/cdk/tools/manipulator/MolecularFormulaManipulator',
  78. "Lorg/openscience/cdk/interfaces/IMolecularFormula;",
  79. "getMolecularFormula",
  80. molecule, use.true.class=FALSE);
  81. formulaJ <- .jcast(formulaJ,"org/openscience/cdk/interfaces/IMolecularFormula")
  82. ## needs that all isotopes contain the properties
  83. string <- .cdkFormula.getString(formulaJ)
  84. objectF <- .cdkFormula.createFormulaObject()
  85. moleculaJT <- .jcall('org/openscience/cdk/tools/manipulator/MolecularFormulaManipulator',
  86. "Lorg/openscience/cdk/interfaces/IMolecularFormula;",
  87. "getMolecularFormula",string,
  88. .jcast(objectF,"org/openscience/cdk/interfaces/IMolecularFormula"),TRUE);
  89. Do <- new(J("java/lang/Integer"), as.integer(charge))
  90. .jcall(moleculaJT,"V","setCharge",Do);
  91. formula <- .cdkFormula.createObject(.jcast(moleculaJT,.IMolecularFormula))
  92. return(formula);
  93. }
  94. #'
  95. #' set.charge.formula
  96. #'
  97. #' Set the charge to a cdkFormula function.
  98. #'
  99. #' @param formula Required. Molecular formula
  100. #' @param charge Optional. Default \code{-1}
  101. #' @export
  102. set.charge.formula <- function(formula,charge = -1) {
  103. if (class(formula) != "cdkFormula")
  104. stop("Supplied object should be a cdkFormula Class")
  105. molecularFormula <- formula@objectJ;
  106. D <- new(J("java/lang/Integer"), as.integer(charge))
  107. .jcall(molecularFormula,"V","setCharge",D);
  108. formula@objectJ <- molecularFormula;
  109. formula@charge <- charge;
  110. return(formula)
  111. }
  112. #'
  113. #' isvalid.formula
  114. #'
  115. #' Validate a cdkFormula.
  116. #'
  117. #' @param formula Required. A CDK Formula
  118. #' @param rule Optional. Default \code{rule=c("nitrogen","RDBE")}
  119. #' @export
  120. isvalid.formula <- function(formula,rule=c("nitrogen","RDBE")){
  121. if (class(formula) != "cdkFormula")
  122. stop("Supplied object should be a cdkFormula Class")
  123. molecularFormula <- formula@objectJ;
  124. nRule <- get("nRule", envir = .rcdk.GlobalEnv)
  125. rdbeRule <- get("rdbeRule", envir = .rcdk.GlobalEnv)
  126. for(i in 1:length(rule)){
  127. ##Nitrogen Rule
  128. if(rule[i] == "nitrogen"){
  129. valid <- .jcall(nRule,"D","validate",molecularFormula);
  130. if(valid != 1.0){
  131. return (FALSE)
  132. }
  133. }
  134. ##RDBE Rule
  135. if(rule[i] == "RDBE"){
  136. valid <- .jcall(rdbeRule,"D","validate",molecularFormula);
  137. if(valid != 1.0){
  138. return (FALSE)
  139. }
  140. else return(TRUE);
  141. }
  142. }
  143. return(TRUE);
  144. }
  145. #'
  146. #' get.isotopes.pattern
  147. #'
  148. #' Generate the isotope pattern given a formula class
  149. #'
  150. #' @param formula Required. A CDK molecule formula
  151. #' @param minAbund Optional. Default \code{0.1}
  152. #' @export
  153. get.isotopes.pattern <- function(formula,minAbund=0.1){
  154. if (class(formula) != "cdkFormula")
  155. stop("Supplied object should be a cdkFormula Class")
  156. molecularFormula <- formula@objectJ;
  157. isoGen <- .jnew("org/openscience/cdk/formula/IsotopePatternGenerator",as.double(minAbund));
  158. isoPattern <- .jcall(isoGen,
  159. "Lorg/openscience/cdk/formula/IsotopePattern;",
  160. "getIsotopes",molecularFormula);
  161. numIP <- .jcall(isoPattern,"I","getNumberOfIsotopes");
  162. ## create a matrix adding the mass and abundance of the isotope pattern
  163. iso.col <- c("mass","abund");
  164. massVSabun <- matrix(ncol=2,nrow=numIP);
  165. colnames(massVSabun)<-iso.col;
  166. for (i in 1:numIP) {
  167. isoContainer <- .jcall(isoPattern,"Lorg/openscience/cdk/formula/IsotopeContainer;","getIsotope",as.integer(i-1));
  168. massVSabun[i,1] <- .jcall(isoContainer,"D","getMass");
  169. massVSabun[i,2] <- .jcall(isoContainer,"D","getIntensity");
  170. }
  171. return (massVSabun);
  172. }
  173. #'
  174. #' generate.formula.iter
  175. #'
  176. #' Generate a list of possible formula objects given a mass and a mass tolerance.
  177. #'
  178. #' @param mass Required. Mass.
  179. #' @param window Optional. Default \code{0.01}
  180. #' @param elements Optional. Default \code{
  181. #' list(c('C', 0,50), c('H', 0,50),
  182. #' c('N', 0,50), c('O', 0,50), c('S', 0,50))}
  183. #' @param validation Optional. Default \code{FALSE}
  184. #' @param charge Optional. Default \code{FALSE}
  185. #' @param as.string Optional. Default \code{FALSE}
  186. #' @export
  187. generate.formula.iter <- function(mass, window = 0.01,
  188. elements = list(
  189. c('C', 0,50),
  190. c('H', 0,50),
  191. c('N', 0,50),
  192. c('O', 0,50),
  193. c('S', 0,50)),
  194. validation = FALSE,
  195. charge = 0.0,
  196. as.string=TRUE) {
  197. mfRange <- .jnew("org/openscience/cdk/formula/MolecularFormulaRange");
  198. ifac <- .jcall("org/openscience/cdk/config/Isotopes",
  199. "Lorg/openscience/cdk/config/Isotopes;",
  200. "getInstance");
  201. for (i in 1:length(elements)) {
  202. ## If the element list is 3, then we have sym, min, max
  203. ## otherwise it should be sym, min, max, massNumber
  204. if (length(elements[[i]]) == 3) {
  205. isotope <- .jcall(ifac,
  206. "Lorg/openscience/cdk/interfaces/IIsotope;",
  207. "getMajorIsotope",
  208. as.character( elements[[i]][1] ), use.true.class=FALSE)
  209. } else if(length(elements[[i]]) == 4) {
  210. isotope <- .jcall(ifac,
  211. "Lorg/openscience/cdk/interfaces/IIsotope;",
  212. "getIsotope",
  213. as.character( elements[[i]][1] ),
  214. as.integer( elements[[i]][4] ),
  215. use.true.class=FALSE)
  216. if (is.null(isotope)) stop(sprintf("Invalid mass number specified for element %s",elements[[i]][1]))
  217. } else stop("Elements must be 3-tuples or 4-tuples")
  218. .jcall(mfRange,
  219. returnSig="V",
  220. method="addIsotope",
  221. isotope,
  222. as.integer( elements[[i]][2] ),
  223. as.integer( elements[[i]][3] )
  224. )
  225. }
  226. ## Construct range strings
  227. ## rstrs <- sapply(names(elements), function(x) paste0(c(x, elements[[x]][1], elements[[x]][2]), sep='', collapse=' '))
  228. ## if (length(rstrs) == 0)
  229. ## warning("The element specification resulted in a 0 length vector. This is worrisome")
  230. ## ## Get MF range object
  231. ## mfRange <- .jcall("org/guha/rcdk/util/Misc",
  232. ## "Lorg/openscience/cdk/formula/MolecularFormulaRange;",
  233. ## "getMFRange",
  234. ## .jarray(rstrs))
  235. ## construct generator
  236. mfgen <- .jnew("org/openscience/cdk/formula/RoundRobinFormulaGenerator",
  237. get("dcob", envir = .rcdk.GlobalEnv),
  238. as.double(mass-window),
  239. as.double(mass+window),
  240. mfRange)
  241. hasNext <- NA
  242. formula <- NA
  243. ## hasNx <- function() {
  244. ## hasNext <<- .jcall(mfgen, "Lorg/openscience/cdk/interfaces/IMolecularFormula;", "getNextFormula")
  245. ## if (is.jnull(hasNext)) {
  246. ## ## nothing to do
  247. ## formula <<- NA
  248. ## } else formula <<- hasNext
  249. ## return(!is.jnull(hasNext))
  250. ## }
  251. nextEl <- function() {
  252. hasNext <<- NA
  253. formula <- .jcall(mfgen, "Lorg/openscience/cdk/interfaces/IMolecularFormula;", "getNextFormula")
  254. if (is.jnull(formula)) stop("StopIteration")
  255. if (!as.string) {
  256. return(formula)
  257. } else {
  258. return(.jcall("org/openscience/cdk/tools/manipulator/MolecularFormulaManipulator",
  259. "S", "getString", formula, FALSE, TRUE))
  260. }
  261. }
  262. ##obj <- list(nextElem = nextEl, hasNext = hasNx)
  263. obj <- list(nextElem = nextEl)
  264. class(obj) <- c("generate.formula2", "abstractiter", "iter")
  265. return(obj)
  266. }
  267. #' generate.formula
  268. #'
  269. #' @param mass Required. Mass.
  270. #' @param window Optional. Default \code{0.01}
  271. #' @param elements Optional. Default \code{
  272. #' list(c('C', 0,50), c('H', 0,50),
  273. #' c('N', 0,50), c('O', 0,50), c('S', 0,50))}
  274. #' @param validation Optional. Default \code{FALSE}
  275. #' @param charge Optional. Default \code{FALSE}
  276. #' @export
  277. generate.formula <- function(mass,
  278. window=0.01,
  279. elements=list(c("C",0,50),c("H",0,50),c("N",0,50),c("O",0,50),c("S",0,50)),
  280. validation=FALSE,
  281. charge=0.0){
  282. builder <- .cdkFormula.createChemObject();
  283. mfTool <- .jnew("org/openscience/cdk/formula/MassToFormulaTool",builder);
  284. ruleList <-.jcast(.jcall("org/guha/rcdk/formula/FormulaTools",
  285. "Ljava/util/List;",
  286. "createList"), "java/util/List")
  287. ## TOLERANCE RULE
  288. toleranceRule <- .jnew("org/openscience/cdk/formula/rules/ToleranceRangeRule");
  289. ruleG <- .jcast(toleranceRule, "org/openscience/cdk/formula/rules/IRule");
  290. D <- new(J("java/lang/Double"), window)
  291. paramsA <- .jarray(list(D,D))
  292. paramsB <- .jcastToArray(paramsA)
  293. .jcall(ruleG,"V","setParameters",paramsB);
  294. ruleList <-.jcall("org/guha/rcdk/formula/FormulaTools", "Ljava/util/List;", "addTo",ruleList,ruleG)
  295. ## ELEMENTS RULE
  296. elementRule <- .jnew("org/openscience/cdk/formula/rules/ElementRule");
  297. ruleG <- .jcast(elementRule, "org/openscience/cdk/formula/rules/IRule");
  298. chemObject <- .cdkFormula.createChemObject();
  299. range <- .jnew("org/openscience/cdk/formula/MolecularFormulaRange");
  300. ifac <- .jcall("org/openscience/cdk/config/Isotopes",
  301. "Lorg/openscience/cdk/config/Isotopes;",
  302. "getInstance");
  303. for (i in 1:length(elements)) {
  304. ## If the element list is 3, then we have sym, min, max
  305. ## otherwise it should be sym, min, max, massNumber
  306. if (length(elements[[i]]) == 3) {
  307. isotope <- .jcall(ifac,
  308. "Lorg/openscience/cdk/interfaces/IIsotope;",
  309. "getMajorIsotope",
  310. as.character( elements[[i]][1] ), use.true.class=FALSE)
  311. } else if(length(elements[[i]]) == 4) {
  312. isotope <- .jcall(ifac,
  313. "Lorg/openscience/cdk/interfaces/IIsotope;",
  314. "getIsotope",
  315. as.character( elements[[i]][1] ),
  316. as.integer( elements[[i]][4] ),
  317. use.true.class=FALSE)
  318. if (is.null(isotope)) stop(sprintf("Invalid mass number specified for element %s",elements[[i]][1]))
  319. } else stop("Elements must be 3-tuples or 4-tuples")
  320. .jcall(range,
  321. returnSig="V",
  322. method="addIsotope",
  323. isotope,
  324. as.integer( elements[[i]][2] ),
  325. as.integer( elements[[i]][3] )
  326. )
  327. }
  328. paramsA <- .jarray(list(range))
  329. paramsB <- .jcastToArray(paramsA)
  330. .jcall(ruleG,"V","setParameters",paramsB);
  331. ruleList <-.jcall("org/guha/rcdk/formula/FormulaTools",
  332. "Ljava/util/List;", "addTo",
  333. .jcast(ruleList,"java/util/List"),
  334. ruleG)
  335. ## Setting the rules int FormulaTools
  336. .jcall(mfTool,"V","setRestrictions",.jcast(ruleList,"java/util/List"));
  337. mfSet <- .jcall(mfTool,"Lorg/openscience/cdk/interfaces/IMolecularFormulaSet;",
  338. "generate",mass);
  339. if (is.null(mfSet))
  340. return(list())
  341. sizeSet <- .jcall(mfSet,"I","size");
  342. ecList <- list();
  343. count = 1;
  344. for (i in 1:sizeSet) {
  345. mf <- .jcall(mfSet,
  346. "Lorg/openscience/cdk/interfaces/IMolecularFormula;",
  347. "getMolecularFormula",
  348. as.integer(i-1));
  349. .jcall(mf,"V","setCharge",new(J("java/lang/Integer"), as.integer(charge)));
  350. object <- .cdkFormula.createObject(.jcast(mf,
  351. "org/openscience/cdk/interfaces/IMolecularFormula"));
  352. isValid = TRUE;
  353. if(validation==TRUE)
  354. isValid = isvalid.formula(object);
  355. if(isValid==TRUE){ ## if it's true add to the list
  356. ecList[[count]] = object;
  357. count = count+1;
  358. }
  359. }
  360. ecList
  361. }
  362. #############################################################
  363. ## Intern functions: Creating object
  364. #############################################################
  365. .cdkFormula.createChemObject <- function(){
  366. get("dcob", envir = .rcdk.GlobalEnv)
  367. # dcob <- .jcall("org/openscience/cdk/DefaultChemObjectBuilder",
  368. # "Lorg/openscience/cdk/interfaces/IChemObjectBuilder;",
  369. # "getInstance")
  370. # dcob
  371. }
  372. .cdkFormula.createFormulaObject <- function(){
  373. ## dcob <- .cdkFormula.createChemObject()
  374. ## klass <- J("org.openscience.cdk.interfaces.IMolecularFormula")$class
  375. ## cfob <- .jcall(dcob,
  376. ## "Lorg/openscience/cdk/interfaces/ICDKObject;",
  377. ## "newInstance",
  378. ## klass
  379. ## );
  380. ## cfob
  381. .jcast(.jnew("org/openscience/cdk/formula/MolecularFormula"),
  382. "org/openscience/cdk/interfaces/IMolecularFormula")
  383. }
  384. #############################################################
  385. ## extract the molecular formula string form the java object
  386. #############################################################
  387. .cdkFormula.getString <- function(molecularFormula) {
  388. if (attr(molecularFormula, "jclass") != 'org/openscience/cdk/interfaces/IMolecularFormula') {
  389. stop("Supplied object should be a Java reference to an IMolecularFormula")
  390. }
  391. formula <- .jcall('org/openscience/cdk/tools/manipulator/MolecularFormulaManipulator',
  392. 'S', 'getString', molecularFormula)
  393. }
  394. #############################################################
  395. ## create a formula class from the molecularFormula java object
  396. #############################################################
  397. .cdkFormula.createObject <- function(molecularformula){
  398. object <-new("cdkFormula")
  399. object@objectJ <- molecularformula;
  400. iterable <- .jcall(molecularformula,"Ljava/lang/Iterable;","isotopes");
  401. isoIter <- .jcall(iterable,"Ljava/util/Iterator;","iterator");
  402. size <- .jcall(molecularformula,"I","getIsotopeCount");
  403. isotopeList = matrix(ncol=3,nrow=size);
  404. colnames(isotopeList) <- c("isoto","number","mass");
  405. for(i in 1:size){
  406. isotope = .jcast(.jcall(isoIter,"Ljava/lang/Object;","next"), "org/openscience/cdk/interfaces/IIsotope");
  407. isotopeList[i,1] <- .jcall(isotope,"S","getSymbol");
  408. isotopeList[i,2] <- .jcall(molecularformula,"I","getIsotopeCount",isotope);
  409. #massNum <- .jcall(isotope,"Ljava/lang/Double;","getMassNumber");
  410. massNum <- isotope$getMassNumber()
  411. #exactMass <- .jcall(isotope,"Ljava/lang/Double;","getExactMass");
  412. exactMass <- isotope$getExactMass()
  413. #print(exactMass)
  414. isotopes <- J("org/openscience/cdk/config/Isotopes")
  415. if (is.null(massNum)) {
  416. isos <- isotopes$getInstance()
  417. majorIsotope <- isos$getMajorIsotope(isotope$getSymbol())
  418. if (!is.null(majorIsotope)) {
  419. exactMass <- majorIsotope$getExactMass()
  420. }
  421. } else {
  422. if (is.null(exactMass)) {
  423. isos <- isotopes$getInstance()
  424. temp <- isos$getIsotope(isotope$getSymbol(), massNum);
  425. if (!is.null(temp)) {
  426. exactMass <- temp$getExactMass()
  427. }
  428. }
  429. }
  430. #ch <- .jcall(isotope,"Ljava/lang/Double;","getExactMass");
  431. isotopeList[i,3] <- exactMass
  432. }
  433. object@string <- .cdkFormula.getString(molecularformula);
  434. manipulator <- get("mfManipulator", envir = .rcdk.GlobalEnv)
  435. cMass <- .jcall(manipulator,"D","getTotalExactMass",molecularformula);
  436. object@mass <- cMass;
  437. chargeDO <- .jcall(molecularformula,"Ljava/lang/Integer;","getCharge");
  438. charge <- .jcall(chargeDO,"D","doubleValue");
  439. object <- set.charge.formula(object,charge)
  440. object@isotopes <- isotopeList;
  441. return(object);
  442. }
  443. #' Construct an isotope pattern similarity calculator.
  444. #'
  445. #' A method that returns an instance of the CDK \code{IsotopePatternSimilarity}
  446. #' class which can be used to compute similarity scores between pairs of
  447. #' isotope abundance patterns.
  448. #'
  449. #' @param tol The tolerance
  450. #' @return A \code{jobjRef} corresponding to an instance of \code{IsotopePatternSimilarity}
  451. #' @seealso \code{\link{compare.isotope.pattern}}
  452. #' @references \url{http://cdk.github.io/cdk/1.5/docs/api/org/openscience/cdk/formula/IsotopePatternSimilarity.html}
  453. #' @author Miguel Rojas Cherto
  454. get.isotope.pattern.similarity <- function(tol = NULL) {
  455. ips <- .jnew("org/openscience/cdk/formula/IsotopePatternSimilarity")
  456. if (!is.null(tol)) ips$seTolerance(tol)
  457. return(ips)
  458. }
  459. #' Construct an isotope pattern generator.
  460. #'
  461. #' Constructs an instance of the CDK \code{IsotopePatternGenerator}, with an optional
  462. #' minimum abundance specified. This object can be used to generate all combinatorial
  463. #' chemical isotopes given a structure.
  464. #'
  465. #' @param minAbundance The minimum abundance
  466. #' @return A \code{jobjRef} corresponding to an instance of \code{IsotopePatternGenerator}
  467. #' @references \url{http://cdk.github.io/cdk/1.5/docs/api/org/openscience/cdk/formula/IsotopePatternGenerator.html}
  468. #' @author Miguel Rojas Cherto
  469. get.isotope.pattern.generator <- function(minAbundance = NULL) {
  470. if (is.null(minAbundance))
  471. .jnew("org/openscience/cdk/formula/IsotopePatternGenerator")
  472. else
  473. .jnew("org/openscience/cdk/formula/IsotopePatternGenerator", as.double(minAbundance))
  474. }
  475. #' Compare isotope patterns.
  476. #'
  477. #' Computes a similarity score between two different isotope abundance patterns.
  478. #'
  479. #' @param iso1 The first isotope pattern, which should be a \code{jobjRef} corresponding to the \code{IsotopePattern} class
  480. #' @param iso2 The second isotope pattern, which should be a \code{jobjRef} corresponding to the \code{IsotopePattern} class
  481. #' @param ips An instance of the \code{IsotopePatternSimilarity} class. if \code{NULL} one will be constructed automatically
  482. #'
  483. #' @return A numeric value between 0 and 1 indicating the similarity between the two patterns
  484. #' @seealso \code{\link{get.isotope.pattern.similarity}}
  485. #' @export
  486. #' @references \url{http://cdk.github.io/cdk/2.3/docs/api/org/openscience/cdk/formula/IsotopePatternSimilarity.html}
  487. #' @author Miguel Rojas Cherto
  488. compare.isotope.pattern <- function(iso1, iso2, ips = NULL) {
  489. cls <- unique(c(class(iso1), class(iso2)))
  490. if (length(cls) != 1) stop("Must supply Java objects of class IsotopePattern")
  491. if (cls != 'jobjRef') stop("Must supply Java objects of class IsotopePattern")
  492. if(attr(iso1, "jclass") != "org/openscience/cdk/formula/IsotopePattern" ||
  493. attr(iso2, "jclass") != "org/openscience/cdk/formula/IsotopePattern") {
  494. stop("Must supply an IsotopePattern")
  495. }
  496. if (is.null(ips)) ips <- get.isotope.pattern.similarity()
  497. return(ips$compare(iso1, iso2))
  498. }