diff --git a/.yardoc/checksums b/.yardoc/checksums new file mode 100644 index 0000000..1e48c8a --- /dev/null +++ b/.yardoc/checksums @@ -0,0 +1,3 @@ +lib/classyfire_api.rb ed7783c1c688d4ee2a91044082a5ac80c3cd3c3e +lib/query_resource.rb 645cfb1688a5c44e67e5227fc0e9a77589731f24 +lib/entity_resource.rb 6c50b4be6a5eb13b44d7080b19c7033b7a37c7cf diff --git a/.yardoc/object_types b/.yardoc/object_types new file mode 100644 index 0000000..8cb81af Binary files /dev/null and b/.yardoc/object_types differ diff --git a/.yardoc/objects/root.dat b/.yardoc/objects/root.dat new file mode 100644 index 0000000..fc0d560 Binary files /dev/null and b/.yardoc/objects/root.dat differ diff --git a/.yardoc/proxy_types b/.yardoc/proxy_types new file mode 100644 index 0000000..beefda1 Binary files /dev/null and b/.yardoc/proxy_types differ diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..e212456 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem 'rest-client' +gem 'yard' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..f77ad1b --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,27 @@ +GEM + remote: https://rubygems.org/ + specs: + domain_name (0.5.20160309) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.2) + domain_name (~> 0.5) + mime-types (2.99.1) + netrc (0.11.0) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + yard (0.8.7.6) + +PLATFORMS + ruby + +DEPENDENCIES + rest-client + yard + +BUNDLED WITH + 1.11.2 diff --git a/README.md b/README.md index 0879518..528fd7e 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,17 @@ > > > >###GET### > > -> >**/entities/{entity_inchikey}** +> >**/entities/{entityInchikey}** > > > >A chemical compound's classification can be retrieved in the JSON or XML format. The compound's information is accessed via the InChIkey as show in the following examples. In this example, the entity has the InChIKey=LABTWGUMFABVFG-ONEGZZNKSA-N. > > > -> > >curl -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://classyfire.wishartlab.com/entities/BDAGIHXWWSANSR-UHFFFAOYSA-N.json +> > >ClassyFireAPI.get_entity_classification("BDAGIHXWWSANSR-UHFFFAOYSA-N","json") +> > +> > Where: +> > +> > >The entity's InChIKey is "BDAGIHXWWSANSR-UHFFFAOYSA-N", +> > > +> > >The output format is "json" (JSON). > ##2. Query## @@ -41,29 +47,33 @@ > >The Query model represents the chemical structure to be classified. Its attributes are the query label and the query input. > > >The query label is an identifier > > > -> > > The query input contains the compound's identifier (optional) and its structural representation, separated by a comma. The chemical structure is represented either in the [Daylight SMILES](http://www.daylight.com/dayhtml/doc/theory/theory.smiles.html) or the [InChI](http://www.iupac.org/home/publications/e-resources/inchi.html) format. +> > >The query input contains the compound's identifier (optional) and its structural representation, separated by a comma. The chemical structure is represented either in the [Daylight SMILES](http://www.daylight.com/dayhtml/doc/theory/theory.smiles.html) or the [InChI](http://www.iupac.org/home/publications/e-resources/inchi.html) format. > > > >###POST### > >A query can be submitted using the POST method as demonstrated in the following example. -> > >curl -is http://localhost:3000/queries.json -X POST -d '{"label":"curl_test","query_input":"MOL1,CCCOCC\nMOL2,COCC=CCCC"}' -H "Content-Type: application/json" +> > >ClassyFireAPI.submit_query("curl_test","MOL1\\tCCCOCC\\nMOL2\\tCOCC=CCCC","STRUCTURE") > > > >where the parameters are: > > > > >The query label: curl_test, > > > -> > >The entity identifiers: ID1,ID2 +> > >The entity identifiers: MOL1,MOL2 > > > > >The entity's structure represented in the SMILES format: CCCOCC and COCC=CCCC. > > +> > >The query is of type 'STRUCTURE' + > >###GET### > > -> >**/queries/{query_id}** +> >**/queries/{queryId}** > > > >The classification results can be retrieved via a GET method in the JSON or XML format. > > > -> > >curl -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://classyfire.wishartlab.com/queries/88.json +> > >ClassyFireAPI.get_query(443431,"json") > > -> >where the query id is 88. +> >where: +> > >The query id is 443431, +> > >The output format is "json" (JSON) # **Directory Structure** # diff --git a/contributors.txt b/contributors.txt index 21b18b9..b92ddc3 100644 --- a/contributors.txt +++ b/contributors.txt @@ -1 +1 @@ -djoumbou +Yannick Djoumbou Feunang diff --git a/doc/ClassyFireAPI.html b/doc/ClassyFireAPI.html new file mode 100644 index 0000000..6a7c99c --- /dev/null +++ b/doc/ClassyFireAPI.html @@ -0,0 +1,1928 @@ + + + + + + Module: ClassyFireAPI + + — Documentation by YARD 0.8.7.6 + + + + + + + + + + + + + + + + + + + + + +

Module: ClassyFireAPI + + + +

+ +
+ + + + + + + + +
Defined in:
+
lib/classyfire_api.rb
+ +
+
+ + +

Constant Summary

+ +
+ +
URL = + +
+
'http://classyfire.wishartlab.com'
+ +
+ + + + + + + + + +

+ Class Method Summary + (collapse) +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + + (Text) get_entity_classification(inchikey, format = "json") + + + + + +

+
+ +

Retrieves the classification results for a given entity.

+ + +
+
+
+

Parameters:

+
    + +
  • + + inchikey + + + (String) + + + + — +
    +

    the ID of the query.

    +
    + +
  • + +
  • + + format + + + (String) + + + (defaults to: "json") + + + — +
    +

    the format of the query, 'text' (either JSON, CSV, or SDF)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Text) + + + + — +
    +

    A text file displaying the classification results for the entity in the +specified format.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
+
# File 'lib/classyfire_api.rb', line 61
+
+def ClassyFireAPI.get_entity_classification(inchikey,format="json")
+  inchikey_id = inchikey.to_s.gsub('InChIKey=','')
+  begin
+    if format == "json"
+      RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :json
+    elsif format == "sdf"
+      RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :sdf
+    elsif format == "csv"
+      RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :csv
+    end 
+  rescue RestClient::ResourceNotFound => e
+    e.response
+  rescue  RestClient::InternalServerError => e
+    e.response
+  rescue RestClient::GatewayTimeout => e
+    e.response
+  rescue RestClient::RequestTimeout => e
+    e.response
+  end
+end
+
+
+ +
+

+ + + (Text) get_query(query_id, format = "json") + + + + + +

+
+ +

Retrieves the classification results for a given query.

+ +

the query's entities in the specified format.

+ + +
+
+
+

Parameters:

+
    + +
  • + + query_id + + + (Integer) + + + + — +
    +

    the ID of the query.

    +
    + +
  • + +
  • + + format + + + (String) + + + (defaults to: "json") + + + — +
    +

    the format of the query (either JSON, CSV, or SDF)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Text) + + + + — +
    +

    A text file displaying the classification results for

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+
+
# File 'lib/classyfire_api.rb', line 36
+
+def ClassyFireAPI.get_query(query_id,format="json")
+  begin
+    if format == "json"
+      RestClient.get "#{URL}/queries/#{query_id}.json", :accept => :json
+    elsif format == "sdf"
+      RestClient.get "#{URL}/queries/#{query_id}.sdf", :accept => :sdf
+    elsif format == "csv"
+      RestClient.get "#{URL}/queries/#{query_id}.csv", :accept => :csv
+    end
+  rescue RestClient::ResourceNotFound => e
+    e.response
+  rescue  RestClient::InternalServerError => e
+    e.response
+  rescue RestClient::GatewayTimeout => e
+    e.response
+  rescue RestClient::RequestTimeout => e
+    e.response
+  end      
+end
+
+
+ +
+

+ + + (String) query_status(query_id) + + + + + +

+
+ +

Retrieves the status of a query

+ + +
+
+
+

Parameters:

+
    + +
  • + + query_id + + + (Integer) + + + + — +
    +

    the ID of the query

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +
    +

    the query status, 'Done' or 'In progress', 'string'

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+85
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'lib/classyfire_api.rb', line 85
+
+def ClassyFireAPI.query_status(query_id)
+  begin
+    RestClient.get "#{URL}/queries/#{query_id}/status.json", :accept => :json
+  rescue Exception=>e
+    $stderr.puts e.message
+    nil
+  end
+end
+
+
+ +
+

+ + + (String) retrieve_classification(input, output) + + + + + +

+
+ +

Reads a tab separated file, and use the structure representation to +retrieve the strutcure's classification from ClassyFire.

+ + +
+
+
+

Parameters:

+
    + +
  • + + input + + + (String) + + + + — +
    +

    path to the input file.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +
    +

    path to the output file.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+
+
# File 'lib/classyfire_api.rb', line 266
+
+def ClassyFireAPI.retrieve_classification(input,output)
+  absolute_path = File.expand_path(input)
+  f_input       = File.open(absolute_path, 'r')
+  h             = Hash.new
+  directory     = absolute_path.split('/')[0...-1].join("/")
+  f_output      = File.new(output, 'w')
+  res = String.new
+
+
+  res += "{"
+  res += '"id": 1,'
+  res += '"label":"' + output + '",' + '"classification_status":"Done",' + '"entities":['
+
+  f_input.each_line do |line|
+    sline = line.strip.split("\t")
+    if sline.length == 1
+      h[sline[0]] = sline[0]
+    elsif sline.length == 2
+      h[sline[0]]  = line.strip
+    end
+  end
+
+  puts h.keys.uniq.length
+  if h.keys.length > 0
+    i = 1
+    h.keys.uniq[0..-1].each do |key|
+      puts i
+
+      puts "#{key} :: #{h[key]}"
+      begin
+        qs = submit_query(key,h[key])
+
+        qs_decoded = JSON.parse(qs)
+        qr = JSON.parse(get_query(qs_decoded["id"],format="json"))
+
+        res += qr["entities"][0].to_json
+        res += ","
+        i += 1
+      rescue Exception => e
+        e.message
+      end
+
+    end
+    key = h.keys[-1]
+    puts "#{key} :: #{h[key]}"
+    begin
+      qs = submit_query(key,h[key])
+      sleep(0.2)
+      qs_decoded = JSON.parse(qs)
+      qr = JSON.parse(get_query(qs_decoded["id"],format="json"))
+      # puts qr["entities"]
+      # sleep(0.2)
+      # f_output.print qr["entities"][0],"\n"
+      res += qr["entities"][0].to_json
+      # res += ","
+    rescue Exception => e
+      e.message
+    end        
+  end
+
+  res += "]}"
+  f_output.print res
+end
+
+
+ +
+

+ + + (String) retrieve_entities_json(input, output) + + + + + +

+
+ +

Reads a tab separated file, and use the structure representation to +retrieve the strutcure's classification from ClassyFire in a JSON +format.

+ + +
+
+
+

Parameters:

+
    + +
  • + + input + + + (String) + + + + — +
    +

    path to the input file

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +
    +

    path to the output file

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+
+
# File 'lib/classyfire_api.rb', line 335
+
+def ClassyFireAPI.retrieve_entities_json(input,output)
+  absolute_path = File.expand_path(input)
+  f_input       = File.open(absolute_path, 'r')
+  h             = Hash.new
+  directory     = absolute_path.split('/')[0...-1].join("/")
+  f_output      = File.new(output, 'w')
+  puts 
+  res = String.new
+
+  res += "{"
+  res += '"id": 1,'
+  res += '"label":"' + output + '",' + '"classification_status":"Done",' + '"entities":['
+
+  f_input.each_line do |line|
+    sline = line.strip.split("\t")
+    h[sline[0]]  = sline[-1]
+  end
+
+  puts h.keys.uniq.length
+  if h.keys.length > 0
+    i = 1
+    h.keys.uniq[0...-1].each do |key|
+      puts i
+      # puts "#{key} :: #{h[key]}"
+      begin
+        inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip
+        # puts inchikey
+        qr = JSON.parse(ClassyFireAPI.get_entity_classification(inchikey,format="json"))
+        qr['identifier'] = key
+        res += qr.to_json
+        res += ","
+        puts "#{key} :: RETURN NIL" if qr.nil? || qr['direct_parent']['name'].nil?
+      rescue Exception => e
+        e.message
+      end
+      i += 1
+    end
+    key = h.keys[-1]
+    # puts "#{key} :: #{h[key]}"
+    begin
+      inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip
+      # puts inchikey
+      qr = JSON.parse(ClassyFireAPI.get_entity_classification(inchikey,format="json"))
+      qr['identifier'] = key
+      res += qr.to_json
+      puts "#{key} :: RETURN NIL" if qr.nil? || qr['direct_parent']['name'].nil?
+      # res += ","
+    rescue Exception => e
+      e.message
+    end        
+  end
+  res += "]}"
+  f_output.print res
+end
+
+
+ +
+

+ + + (String) retrieve_entities_sdf(input, output) + + + + + +

+
+ +

Reads a tab separated file, and use the structure representation to +retrieve the strutcure's classification from ClassyFire in a SDF +format.

+ + +
+
+
+

Parameters:

+
    + +
  • + + input + + + (String) + + + + — +
    +

    path to the input file

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +
    +

    path to the output file

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+
+
# File 'lib/classyfire_api.rb', line 397
+
+def ClassyFireAPI.retrieve_entities_sdf(input,output)
+  absolute_path = File.expand_path(input)
+  f_input       = File.open(absolute_path, 'r')
+  h             = Hash.new
+  directory     = absolute_path.split('/')[0...-1].join("/")
+  f_output      = File.new(output, 'w')
+  res = String.new
+
+  f_input.each_line do |line|
+    sline = line.strip.split("\t")
+    h[sline[0]]  = sline[-1]
+  end
+
+  puts h.keys.uniq.length
+  if h.keys.length > 0
+    i = 1
+    h.keys.uniq[0...-1].each do |key|
+      puts i
+      # puts "#{key} :: #{h[key]}"
+      begin
+        inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip
+        # puts inchikey
+        qr = ClassyFireAPI.get_entity_classification(inchikey,format="sdf")
+        if qr.include?("The page you were looking for doesn't exist")
+          puts "The page you were looking for doesn't exist"
+        elsif qr.empty?
+
+        else
+          input = qr.split("\n")[1..-1].join("\n")
+          puts input
+          f_output.puts "#{key}\n"
+          f_output.puts input
+        end
+      rescue Exception => e
+        e.message
+      end
+      i += 1
+    end
+    key = h.keys[-1]
+    # puts "#{key} :: #{h[key]}"
+    begin
+      inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip
+      # puts inchikey
+      qr = ClassyFireAPI.get_entity_classification(inchikey,format="sdf")
+      if qr.include?("The page you were looking for doesn't exist")
+        puts "The page you were looking for doesn't exist"
+      elsif qr.empty?
+
+      else
+        input = qr.split("\n")[1..-1].join("\n")
+        puts input
+        f_output.puts "#{key}\n"
+        f_output.puts input
+      end
+    rescue Exception => e
+      e.message
+    end        
+  end
+  # f_output.print res
+end
+
+
+ +
+

+ + + (Object) submit_queries_from_directory(folder, slice_length, type = "STRUCTURE") + + + + + +

+
+ +

Takes each file in a folder, and submit the contained structures in bluks +of a given size.

+ +

For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must +contain either

+ +
1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name
+  for the 'IUPAC NAME' query type.
+2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the 
+  'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type.
+ +

For 'FASTA' query type, just submit the query as a standard FASTA +text. @param: input_file [String] The path to the folder. @param: +slice_length [Integer] The maximum number of entries for each query input +(each file is fragmented into n part of #slice_length entries each), +'integer'

+ + +
+
+
+

Parameters:

+
    + +
  • + + type + + + (String) + + + (defaults to: "STRUCTURE") + + + — +
    +

    the query_type 'STRUCTURE' (default) or 'IUPAC_NAME' or +'FASTA'

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+
+
# File 'lib/classyfire_api.rb', line 184
+
+def ClassyFireAPI.submit_queries_from_directory(folder,slice_length,type="STRUCTURE")
+  if File.directory?(folder)
+    Dir.foreach(folder) do |filename|
+      puts "Filename: #{filename}"
+      ClassyFireAPI.submit_query_input_in_chunks(folder+"/"+filename,slice_length, type) unless filename == "." || filename == ".." || filename == ".DS_Store"
+    end
+  else
+    $stderr.puts "#{folder} is not a folder."
+  end
+end
+
+
+ +
+

+ + + (Hash) submit_query(label, input, type = 'STRUCTURE') + + + + + +

+
+ +

Submits a ClassyFire query, which should be returned in a specific format.

+ +

if there is an error.

+ + +
+
+
+

Parameters:

+
    + +
  • + + label + + + (String) + + + + — +
    +

    the label of the query.

    +
    + +
  • + +
  • + + input + + + (String) + + + + — +
    +

    the input of the query.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +
    +

    A Ruby Hash with the id (and other attributes) of the Query or nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+
+
# File 'lib/classyfire_api.rb', line 13
+
+def ClassyFireAPI.submit_query(label,input, type='STRUCTURE')
+  begin
+    q = RestClient.post URL+'/queries', {:label => label, :query_input => input, :query_type => type}.to_json, :accept => :json, :content_type => :json
+  rescue RestClient::BadRequest => e
+    e.response
+  rescue  RestClient::InternalServerError => e
+    e.response
+  rescue RestClient::GatewayTimeout => e
+    e.response
+  rescue RestClient::RequestTimeout => e
+    e.response
+  rescue RestClient::UnprocessableEntity => e
+    e.response
+  end
+  q
+end
+
+
+ +
+

+ + + (Object) submit_query_input_in_chunks(input_file, slice_length, start, type = 'STRUCTURE') + + + + + +

+
+ +

Takes a tab-separated file and submit the contained structures in bulks of +a given size

+ +

For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must +contain either

+ +
1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name
+  for the 'IUPAC NAME' query type.
+2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the 
+  'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type.
+ +

For 'FASTA' query type, just submit the query as a standard FASTA +text. @param: slice_length [Integer] The maximum number of entries for each +query input (the whole file is fragmented into n part of #slice_length +entries each). @param: start [Integer] The starting index. Submit +framgments from the index 'start'.

+ + +
+
+
+

Parameters:

+
    + +
  • + + input_file + + + (Text) + + + + — +
    +

    The path to the input file.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+
+
# File 'lib/classyfire_api.rb', line 107
+
+def ClassyFireAPI.submit_query_input_in_chunks(input_file,slice_length, start, type='STRUCTURE')
+  @start_time = Time.now
+  absolute_path = File.expand_path(input_file)
+  f             = File.open(absolute_path, 'r')
+  input         = []
+
+  lines = File.readlines(absolute_path)
+
+  lines.uniq.each do |line|
+    sline = line.strip.split("\t")
+    if sline.length == 1
+      input <<"#{sline[0]}"
+    elsif sline.length >= 2
+      input <<"#{sline[0]}\t#{sline[2]}"
+    end
+  end
+
+  query_ids = []
+  subdivised_groups = input.uniq.each_slice(slice_length).to_a
+  puts "nr of subdivised_groups: #{subdivised_groups.length}"
+  puts subdivised_groups[0]
+  sleeping_time = 120
+  initial_nr_of_jobs = 60
+  i = start
+
+  while i <  initial_nr_of_jobs
+    title     = File.basename(absolute_path).split(".")[0] + "_yannick" + "_part_#{i}"
+
+    begin
+      puts "submitting #{title}"
+      q       = submit_query(title,subdivised_groups[i-1].join("\n"),type)
+      query_ids << JSON.parse(q)['id']
+    rescue Exception => e  
+      puts e.message  
+      puts e.backtrace.inspect
+    end
+    i = i + 1
+  end
+
+  puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s."
+  sleep(sleeping_time)
+  puts "Waking up at #{Time.now - @start_time}"
+
+  while i < subdivised_groups.length
+    k = 0
+    for k in (i..(i+80))
+      title     = File.basename(absolute_path).split(".")[0] + "_yannick" + "_part_#{k}"
+      i = i + 1
+      begin
+        puts "submitting #{title}"
+        q = submit_query(title,subdivised_groups[k-1].join("\n"),type)
+      rescue Exception => e  
+        puts e.message  
+        puts e.backtrace.inspect
+      end
+      
+    end
+    i = k
+    puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s."
+    sleep(sleeping_time)
+    puts "Waking up at #{Time.now - @start_time}"
+  end
+end
+
+
+ +
+

+ + + (Object) submit_random_subset_of_query_input_in_chunks(tab_separated_input_file, size, type = 'STRUCTURE') + + + + + +

+
+ +

Takes a tab-separated file and submit randomly selected structures in bulks +of a given size.

+ +

For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must +contain either

+ +
1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name
+  for the 'IUPAC NAME' query type.
+2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the 
+  'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type.
+ +

For 'FASTA' query type, just submit the query as a standard FASTA +text. is fragmented into n part of #slice_length entries each).

+ + +
+
+
+

Parameters:

+
    + +
  • + + tab_separated_input_file + + + (Text) + + + + — +
    +

    The path to the input file.

    +
    + +
  • + +
  • + + size + + + (Integer) + + + + — +
    +

    The maximum number of entries for each query input (the whole file

    +
    + +
  • + +
  • + + type + + + (String) + + + (defaults to: 'STRUCTURE') + + + — +
    +

    The query_type, 'STRUCTURE' (default) or 'IUPAC_NAME' or +'FASTA'.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+
+
# File 'lib/classyfire_api.rb', line 209
+
+def ClassyFireAPI.submit_random_subset_of_query_input_in_chunks(tab_separated_input_file,size, type='STRUCTURE')
+  @start_time = Time.now
+  absolute_path = File.expand_path(tab_separated_input_file)
+  f             = File.open(absolute_path, 'r')
+  input         = []
+
+  f.each_line do |line|
+
+    sline = line.strip.split("\t")
+    if sline.length == 1
+      input <<"#{sline[0]}"
+    elsif sline.length == 2
+      input <<"#{sline[0]}\t#{sline[1]}"
+    end
+  end
+
+  query_ids = []
+  indexes = []
+  r = 1
+  while r <= (size)
+    s = rand(0..(input.length - 1))
+    unless indexes.include?(s)
+      indexes<<s
+      r += 1
+    end
+  end
+
+  random_subset = indexes.map{|x| input[x]}
+  subdivised_groups = random_subset.each_slice(100).to_a
+  sleeping_time = 120
+
+  i = 0
+  while i < subdivised_groups.length
+    k = 0
+    for k in (i..(i + 5))
+      title     = File.basename(absolute_path).split(".")[0] + "_yannick" + "_part_#{k+1}"
+      i = i + 1
+      begin
+        puts "submitting #{title}"
+        q = submit_query(title,subdivised_groups[k].join("\n"),type)
+      rescue Exception => e  
+        puts e.message  
+        puts e.backtrace.inspect
+      end
+    end
+    i = k
+    puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s."
+    sleep(sleeping_time)
+    puts "Waking up at #{Time.now - @start_time}"
+  end
+end
+
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/doc/EntityResource.html b/doc/EntityResource.html new file mode 100644 index 0000000..5fe5906 --- /dev/null +++ b/doc/EntityResource.html @@ -0,0 +1,123 @@ + + + + + + Class: EntityResource + + — Documentation by YARD 0.8.7.6 + + + + + + + + + + + + + + + + + + + + + +

Class: EntityResource + + + +

+ +
+ +
Inherits:
+
+ ActiveResource::Base + +
    +
  • Object
  • + + + + + +
+ show all + +
+ + + + + + + + + +
Defined in:
+
lib/entity_resource.rb
+ +
+
+ + + + + + + + + + + +
+ + + + + \ No newline at end of file diff --git a/doc/QueryResource.html b/doc/QueryResource.html new file mode 100644 index 0000000..2611f26 --- /dev/null +++ b/doc/QueryResource.html @@ -0,0 +1,192 @@ + + + + + + Class: QueryResource + + — Documentation by YARD 0.8.7.6 + + + + + + + + + + + + + + + + + + + + + +

Class: QueryResource + + + +

+ +
+ +
Inherits:
+
+ ActiveResource::Base + +
    +
  • Object
  • + + + + + +
+ show all + +
+ + + + + + + + + +
Defined in:
+
lib/query_resource.rb
+ +
+
+ + + + + + + + + +

+ Instance Method Summary + (collapse) +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + - (Object) to_param + + + + + +

+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/query_resource.rb', line 7
+
+def to_param
+  self.identifier
+end
+
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_index.html b/doc/_index.html new file mode 100644 index 0000000..f8f7858 --- /dev/null +++ b/doc/_index.html @@ -0,0 +1,136 @@ + + + + + + Documentation by YARD 0.8.7.6 + + + + + + + + + + + + + + + + + + + + + +

Documentation by YARD 0.8.7.6

+
+

Alphabetic Index

+ +

File Listing

+ + +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + + + + + + + + + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/doc/class_list.html b/doc/class_list.html new file mode 100644 index 0000000..2a62e5e --- /dev/null +++ b/doc/class_list.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + Class List + + + + +
+

Class List

+ + + + +
+ + diff --git a/doc/css/common.css b/doc/css/common.css new file mode 100644 index 0000000..cf25c45 --- /dev/null +++ b/doc/css/common.css @@ -0,0 +1 @@ +/* Override this file with custom rules */ \ No newline at end of file diff --git a/doc/css/full_list.css b/doc/css/full_list.css new file mode 100644 index 0000000..c918cf1 --- /dev/null +++ b/doc/css/full_list.css @@ -0,0 +1,57 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; } +#full_list ul { padding: 0; } +#full_list li { padding: 5px; padding-left: 12px; margin: 0; font-size: 1.1em; list-style: none; } +#noresults { padding: 7px 12px; } +#content.insearch #noresults { margin-left: 7px; } +ul.collapsed ul, ul.collapsed li { display: none; } +ul.collapsed.search_uncollapsed { display: block; } +ul.collapsed.search_uncollapsed li { display: list-item; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } +li { color: #888; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.r1 { background: #f0f0f0; } +li.r2 { background: #fafafa; } +li:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a:link, a:visited { text-decoration: none; color: #05a; } +li.clicked { background: #05a; color: #ccc; } +li.clicked a:link, li.clicked a:visited { color: #eee; } +li.clicked a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } +#nav { margin-left: 10px; font-size: 0.9em; display: none; color: #aaa; } +#nav a:link, #nav a:visited { color: #358; } +#nav a:hover { background: transparent; color: #5af; } +.frames #nav span:after { content: ' | '; } +.frames #nav span:last-child:after { content: ''; } + +.frames #content h1 { margin-top: 0; } +.frames li { white-space: nowrap; cursor: normal; } +.frames li small { display: block; font-size: 0.8em; } +.frames li small:before { content: ""; } +.frames li small:after { content: ""; } +.frames li small.search_info { display: none; } +.frames #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } +.frames #content.insearch #search { background-position: center right; } +.frames #search input { width: 110px; } +.frames #nav { display: block; } + +#full_list.insearch li { display: none; } +#full_list.insearch li.found { display: list-item; padding-left: 10px; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/doc/css/style.css b/doc/css/style.css new file mode 100644 index 0000000..96307c5 --- /dev/null +++ b/doc/css/style.css @@ -0,0 +1,339 @@ +body { + padding: 0 20px; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; +} +body.frames { padding: 0 5px; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; +} +h2 small { font-weight: normal; font-size: 0.7em; display: block; float: right; } +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link, .docstring .object_link { font-family: monospace; } +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/doc/method_list.html b/doc/method_list.html new file mode 100644 index 0000000..324e0cb --- /dev/null +++ b/doc/method_list.html @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + Method List + + + + +
+

Method List

+ + + + +
+ + diff --git a/doc/top-level-namespace.html b/doc/top-level-namespace.html new file mode 100644 index 0000000..5c5e989 --- /dev/null +++ b/doc/top-level-namespace.html @@ -0,0 +1,114 @@ + + + + + + Top Level Namespace + + — Documentation by YARD 0.8.7.6 + + + + + + + + + + + + + + + + + + + + + +

Top Level Namespace + + + +

+ +
+ + + + + + + + +
+
+ +

Defined Under Namespace

+

+ + + Modules: ClassyFireAPI + + + + Classes: EntityResource, QueryResource + + +

+ + + + + + + + + +
+ + + + + \ No newline at end of file diff --git a/lib/classyfire_api.rb b/lib/classyfire_api.rb index 9297b78..82bf645 100644 --- a/lib/classyfire_api.rb +++ b/lib/classyfire_api.rb @@ -1,12 +1,18 @@ require 'JSON' -require 'RestClient' +require 'csv' module ClassyFireAPI URL = 'http://classyfire.wishartlab.com' - def ClassyFireAPI.submit_query(label,input) + # Submits a ClassyFire query, which should be returned in a specific format. + # + # @param label [String] the label of the query. + # @param input[String] the input of the query. + # @return [Hash] A Ruby Hash with the id (and other attributes) of the Query or nil + # if there is an error. + def ClassyFireAPI.submit_query(label,input, type='STRUCTURE') begin - RestClient.post URL+'/queries', {:label => label, :query_input => input}.to_json, :accept => :json, :content_type => :json + q = RestClient.post URL+'/queries', {:label => label, :query_input => input, :query_type => type}.to_json, :accept => :json, :content_type => :json rescue RestClient::BadRequest => e e.response rescue RestClient::InternalServerError => e @@ -15,18 +21,26 @@ module ClassyFireAPI e.response rescue RestClient::RequestTimeout => e e.response + rescue RestClient::UnprocessableEntity => e + e.response end + q end + # Retrieves the classification results for a given query. + # + # @param query_id [Integer] the ID of the query. + # @param format [String] the format of the query (either JSON, CSV, or SDF) + # @return [Text] A text file displaying the classification results for + # the query's entities in the specified format. def ClassyFireAPI.get_query(query_id,format="json") - # format can be either 'json' or 'sdf' begin if format == "json" - puts "#{URL}/queries/#{query_id}.json" RestClient.get "#{URL}/queries/#{query_id}.json", :accept => :json elsif format == "sdf" - puts "#{URL}/queries/#{query_id}.sdf" RestClient.get "#{URL}/queries/#{query_id}.sdf", :accept => :sdf + elsif format == "csv" + RestClient.get "#{URL}/queries/#{query_id}.csv", :accept => :csv end rescue RestClient::ResourceNotFound => e e.response @@ -39,14 +53,20 @@ module ClassyFireAPI end end + # Retrieves the classification results for a given entity. + # + # @param inchikey [String] the ID of the query. + # @param format [String] the format of the query, 'text' (either JSON, CSV, or SDF) + # @return [Text] A text file displaying the classification results for the entity in the specified format. def ClassyFireAPI.get_entity_classification(inchikey,format="json") - # format can be either 'json' or 'sdf' inchikey_id = inchikey.to_s.gsub('InChIKey=','') begin if format == "json" RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :json elsif format == "sdf" RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :sdf + elsif format == "csv" + RestClient.get "#{URL}/entities/#{inchikey_id}.#{format}", :accept => :csv end rescue RestClient::ResourceNotFound => e e.response @@ -59,12 +79,379 @@ module ClassyFireAPI end end + # Retrieves the status of a query + # @param query_id [Integer] the ID of the query + # @return [String] the query status, 'Done' or 'In progress', 'string' def ClassyFireAPI.query_status(query_id) - s = JSON.parse(get_query(query_id)) - if s['error'] - s - elsif s['classification_status:'] - s['classification_status'] + begin + RestClient.get "#{URL}/queries/#{query_id}/status.json", :accept => :json + rescue Exception=>e + $stderr.puts e.message + nil end end + + # Takes a tab-separated file and submit the contained structures in bulks of a given size + # + # For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must contain either + # 1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name + # for the 'IUPAC NAME' query type. + # 2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the + # 'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type. + # + # For 'FASTA' query type, just submit the query as a standard FASTA text. + # @param input_file [Text] The path to the input file. + # @param: slice_length [Integer] The maximum number of entries for each query input (the whole file + # is fragmented into n part of #slice_length entries each). + # @param: start [Integer] The starting index. Submit framgments from the index 'start'. + def ClassyFireAPI.submit_query_input_in_chunks(input_file,slice_length, start, type='STRUCTURE') + @start_time = Time.now + absolute_path = File.expand_path(input_file) + f = File.open(absolute_path, 'r') + input = [] + + lines = File.readlines(absolute_path) + + lines.uniq.each do |line| + sline = line.strip.split("\t") + if sline.length == 1 + input <<"#{sline[0]}" + elsif sline.length >= 2 + input <<"#{sline[0]}\t#{sline[2]}" + end + end + + query_ids = [] + subdivised_groups = input.uniq.each_slice(slice_length).to_a + puts "nr of subdivised_groups: #{subdivised_groups.length}" + puts subdivised_groups[0] + sleeping_time = 120 + initial_nr_of_jobs = 60 + i = start + + while i < initial_nr_of_jobs + title = File.basename(absolute_path).split(".")[0] + "_yannick" + "_part_#{i}" + + begin + puts "submitting #{title}" + q = submit_query(title,subdivised_groups[i-1].join("\n"),type) + query_ids << JSON.parse(q)['id'] + rescue Exception => e + puts e.message + puts e.backtrace.inspect + end + i = i + 1 + end + + puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s." + sleep(sleeping_time) + puts "Waking up at #{Time.now - @start_time}" + + while i < subdivised_groups.length + k = 0 + for k in (i..(i+80)) + title = File.basename(absolute_path).split(".")[0] + "_yannick" + "_part_#{k}" + i = i + 1 + begin + puts "submitting #{title}" + q = submit_query(title,subdivised_groups[k-1].join("\n"),type) + rescue Exception => e + puts e.message + puts e.backtrace.inspect + end + + end + i = k + puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s." + sleep(sleeping_time) + puts "Waking up at #{Time.now - @start_time}" + end + end + + # Takes each file in a folder, and submit the contained structures in bluks of a given size. + # + # For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must contain either + # 1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name + # for the 'IUPAC NAME' query type. + # 2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the + # 'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type. + # + # For 'FASTA' query type, just submit the query as a standard FASTA text. + # @param: input_file [String] The path to the folder. + # @param: slice_length [Integer] The maximum number of entries for each query input (each file + # is fragmented into n part of #slice_length entries each), 'integer' + # @param type [String] the query_type 'STRUCTURE' (default) or 'IUPAC_NAME' or 'FASTA' + def ClassyFireAPI.submit_queries_from_directory(folder,slice_length,type="STRUCTURE") + if File.directory?(folder) + Dir.foreach(folder) do |filename| + puts "Filename: #{filename}" + ClassyFireAPI.submit_query_input_in_chunks(folder+"/"+filename,slice_length, type) unless filename == "." || filename == ".." || filename == ".DS_Store" + end + else + $stderr.puts "#{folder} is not a folder." + end + end + + + # Takes a tab-separated file and submit randomly selected structures in bulks of a given size. + # + # For 'STRUCTURE' or 'IUPAC_NAME'query types, each line must contain either + # 1) Only a structural represenation: SMILES, InChI for the 'STRUCTURE' query_type or a IUPAC name + # for the 'IUPAC NAME' query type. + # 2) a tab-separated pair of an ID and the corresponding sructure representation: SMILES, InChI for the + # 'STRUCTURE' query_type or a IUPAC name for the 'IUPAC NAME' query type. + # + # For 'FASTA' query type, just submit the query as a standard FASTA text. + # @param tab_separated_input_file [Text] The path to the input file. + # @param size [Integer] The maximum number of entries for each query input (the whole file + # is fragmented into n part of #slice_length entries each). + # @param type [String] The query_type, 'STRUCTURE' (default) or 'IUPAC_NAME' or 'FASTA'. + def ClassyFireAPI.submit_random_subset_of_query_input_in_chunks(tab_separated_input_file,size, type='STRUCTURE') + @start_time = Time.now + absolute_path = File.expand_path(tab_separated_input_file) + f = File.open(absolute_path, 'r') + input = [] + + f.each_line do |line| + + sline = line.strip.split("\t") + if sline.length == 1 + input <<"#{sline[0]}" + elsif sline.length == 2 + input <<"#{sline[0]}\t#{sline[1]}" + end + end + + query_ids = [] + indexes = [] + r = 1 + while r <= (size) + s = rand(0..(input.length - 1)) + unless indexes.include?(s) + indexes< e + puts e.message + puts e.backtrace.inspect + end + end + i = k + puts "Going to sleep at #{Time.now - @start_time} for #{sleeping_time} s." + sleep(sleeping_time) + puts "Waking up at #{Time.now - @start_time}" + end + end + + # Reads a tab separated file, and use the structure representation + #to retrieve the strutcure's classification from ClassyFire. + # + # @param input [String] path to the input file. + # @return [String] path to the output file. + def ClassyFireAPI.retrieve_classification(input,output) + absolute_path = File.expand_path(input) + f_input = File.open(absolute_path, 'r') + h = Hash.new + directory = absolute_path.split('/')[0...-1].join("/") + f_output = File.new(output, 'w') + res = String.new + + + res += "{" + res += '"id": 1,' + res += '"label":"' + output + '",' + '"classification_status":"Done",' + '"entities":[' + + f_input.each_line do |line| + sline = line.strip.split("\t") + if sline.length == 1 + h[sline[0]] = sline[0] + elsif sline.length == 2 + h[sline[0]] = line.strip + end + end + + puts h.keys.uniq.length + if h.keys.length > 0 + i = 1 + h.keys.uniq[0..-1].each do |key| + puts i + + puts "#{key} :: #{h[key]}" + begin + qs = submit_query(key,h[key]) + + qs_decoded = JSON.parse(qs) + qr = JSON.parse(get_query(qs_decoded["id"],format="json")) + + res += qr["entities"][0].to_json + res += "," + i += 1 + rescue Exception => e + e.message + end + + end + key = h.keys[-1] + puts "#{key} :: #{h[key]}" + begin + qs = submit_query(key,h[key]) + sleep(0.2) + qs_decoded = JSON.parse(qs) + qr = JSON.parse(get_query(qs_decoded["id"],format="json")) + # puts qr["entities"] + # sleep(0.2) + # f_output.print qr["entities"][0],"\n" + res += qr["entities"][0].to_json + # res += "," + rescue Exception => e + e.message + end + end + + res += "]}" + f_output.print res + end + + # Reads a tab separated file, and use the structure representation + # to retrieve the strutcure's classification from ClassyFire in a JSON format. + # + # @param input [String] path to the input file + # @return [String] path to the output file + def ClassyFireAPI.retrieve_entities_json(input,output) + absolute_path = File.expand_path(input) + f_input = File.open(absolute_path, 'r') + h = Hash.new + directory = absolute_path.split('/')[0...-1].join("/") + f_output = File.new(output, 'w') + puts + res = String.new + + res += "{" + res += '"id": 1,' + res += '"label":"' + output + '",' + '"classification_status":"Done",' + '"entities":[' + + f_input.each_line do |line| + sline = line.strip.split("\t") + h[sline[0]] = sline[-1] + end + + puts h.keys.uniq.length + if h.keys.length > 0 + i = 1 + h.keys.uniq[0...-1].each do |key| + puts i + # puts "#{key} :: #{h[key]}" + begin + inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip + # puts inchikey + qr = JSON.parse(ClassyFireAPI.get_entity_classification(inchikey,format="json")) + qr['identifier'] = key + res += qr.to_json + res += "," + puts "#{key} :: RETURN NIL" if qr.nil? || qr['direct_parent']['name'].nil? + rescue Exception => e + e.message + end + i += 1 + end + key = h.keys[-1] + # puts "#{key} :: #{h[key]}" + begin + inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip + # puts inchikey + qr = JSON.parse(ClassyFireAPI.get_entity_classification(inchikey,format="json")) + qr['identifier'] = key + res += qr.to_json + puts "#{key} :: RETURN NIL" if qr.nil? || qr['direct_parent']['name'].nil? + # res += "," + rescue Exception => e + e.message + end + end + res += "]}" + f_output.print res + end + + + + # Reads a tab separated file, and use the structure representation + # to retrieve the strutcure's classification from ClassyFire in a SDF format. + # + # @param input [String] path to the input file + # @return [String] path to the output file + def ClassyFireAPI.retrieve_entities_sdf(input,output) + absolute_path = File.expand_path(input) + f_input = File.open(absolute_path, 'r') + h = Hash.new + directory = absolute_path.split('/')[0...-1].join("/") + f_output = File.new(output, 'w') + res = String.new + + f_input.each_line do |line| + sline = line.strip.split("\t") + h[sline[0]] = sline[-1] + end + + puts h.keys.uniq.length + if h.keys.length > 0 + i = 1 + h.keys.uniq[0...-1].each do |key| + puts i + # puts "#{key} :: #{h[key]}" + begin + inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip + # puts inchikey + qr = ClassyFireAPI.get_entity_classification(inchikey,format="sdf") + if qr.include?("The page you were looking for doesn't exist") + puts "The page you were looking for doesn't exist" + elsif qr.empty? + + else + input = qr.split("\n")[1..-1].join("\n") + puts input + f_output.puts "#{key}\n" + f_output.puts input + end + rescue Exception => e + e.message + end + i += 1 + end + key = h.keys[-1] + # puts "#{key} :: #{h[key]}" + begin + inchikey = %x(/Applications/ChemAxon/JChem/bin/molconvert inchikey -s "#{h[key]}").strip + # puts inchikey + qr = ClassyFireAPI.get_entity_classification(inchikey,format="sdf") + if qr.include?("The page you were looking for doesn't exist") + puts "The page you were looking for doesn't exist" + elsif qr.empty? + + else + input = qr.split("\n")[1..-1].join("\n") + puts input + f_output.puts "#{key}\n" + f_output.puts input + end + rescue Exception => e + e.message + end + end + # f_output.print res + end end \ No newline at end of file diff --git a/lib/entity_resource.rb b/lib/entity_resource.rb index cbebcd6..badfa2b 100644 --- a/lib/entity_resource.rb +++ b/lib/entity_resource.rb @@ -1,7 +1,6 @@ require 'active_resource' class EntityResource < ActiveResource::Base - self.site ='http://localhost:3000' + self.site ='http://classyfire.wishartlab.com' self.element_name = "entity" - end \ No newline at end of file diff --git a/lib/query_resource.rb b/lib/query_resource.rb index decfee1..9d17a11 100644 --- a/lib/query_resource.rb +++ b/lib/query_resource.rb @@ -1,7 +1,7 @@ require 'active_resource' class QueryResource < ActiveResource::Base - self.site ='http://localhost:3000' + self.site ='http://classyfire.wishartlab.com' self.element_name = "query" has_many :entities, class_name: 'EntityResource' def to_param