chemcop.pl
{
/* _____________________________________________________________________________________
Copyright (C) DataAspects Corp 1998
Module Name = chemcop.pl
Description= A TRIMpl program that runs on a remote Daylight Server and
calls various 'c' programs that use Daylight tools to
interact with a Thor chemical database. Chemcop.pl is
called by client programs via the TRIMrpc (TRIM remote
procedure call) utility. Chemcop.pl takes three parameters:
Parameters = parm.0- action (i.e. 'db_exec': Client wants to execute remote program)
parm.1- flag (i.e. 'load', flag to run a program that loads a 'TDT' )
parm.2- list (list with data required by the program, i.e. a 'TDT')
Programs = Chemcop.pl is built from blocks of code. Each block is identified
by a flag. When called, a block executes a remote
program that sends data to and from Thor, Merlin or the tool kit.
The chemcop.pl blocks are:
1. 'load' executes a UNIX script 'load_cis' which takes a
'TDT' argument and inserts it into Thor.
2. 'purge' executes a UNIX script 'purge_tdt' which takes a
'TDT' argument of a SMILES. It keeps the SMILES, but purges
all other data from its TDT.
3. 'unique' executes 'unique_smile.c' which takes a 'SMILES' argument
and returns a USMILES.
4. 'is_smi_in_db' executes 'is_smi_in_db.c' which takes a 'SMILES'
argument and returns TRUE/FALSE and error codes.
5. 'get_chem_dat' executes 'get_data_from_cis.c' which takes a 'SMILES'
or structure number and returns USMILES, MF, MW, CAS and ClogP.
6. 'get_thorlist' executes 'wrno_list_from_cis' which takes a list of
structure numbers and returns WRNO,CAS,MW,MF,SMILES.
7. 'minimer' executes minimer.c which takes a 'Merlin Pool Name',
'SMILES' and '# hits', executes a similarity search, and returns
a list of hits with each row containing a 'similiarity index',
'WRNO', and 'SMILES'.
8. 'minimer_gen' executes 'minimer_gen.c' which takes five user defined
parameters ( Merlin pool name, search type, search field, search value,
number of hits) and returns a list with six fields (structure number,
search column, CAS, MW, MF, Similarity index, and SMILES).
9. 'foreign_thor' executes 'search_foreign.c' which takes three parameters
('dbname' 'datatype' 'search_value') and returns SMILES, WRNO, MF, MW,
CAS.
10. 'listmerlin' executes a UNIX script called listmerlin which returns
the names on the Merlin that are currently open.
11. 'listthor' executes a UNIX script called listthor which returns
the names of the Thor databases that are currently open.
12. 'pingchemcop' calls 'chemcop.run' to return a 'hello' message and
write a 'hello' message to chemcop.log on ChemServer.
13. 'pingmerlin' executes a UNIX script called 'pingmerlin' which takes
the name of a Merlin pool as a parameter and returns its 'open'
status.
14. 'pingthor' executes a UNIX script called 'pingthor' which takes
the name of a Thor database as a parameter and returns its 'open'
status.
15. 'smi2mol'executes a C program called 'smi2mol' which takes
a SMILES as a parameter and returns a molfile.
Revisions: 17 June 00, added smi2mol.
...Pat McGreevy, 18 Feb 99 [McG, 18 June00]
_____________________________________________________________________________________ */
char fn[128],fn1[128],fn2[128];
int rc;
list ll;
#define logfile "/usr2/trim/run/chemcop.log"
/*#define loging turn on logging */
#undef loging /* turn off logging */
#ifdef logging
log(logfile,"----------");
log(logfile,to_char(SYSDATE,"DD-MON HH:MI:SS"));
if (count(parm))
log(logfile,"parm.0= "^^parm.0);
if (count(parm) == 2)
log(logfile,"parm.1= "^^parm.1);
if (count(parm) == 3){
log(logfile,"parm.1: "^^parm.1);
log(logfile,"parm.2: "^^list_curr(parm.2,0));
}
#endif
rc= NULL;
if (parm.0 == db_exec) { /* client wants to execute a command */
if (parm.1 == "thor_load") { /* 'load' TDT from client into Thor */
fn1 = tmpnam(); /* create filename & assign it to fn1 */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
list_file(parm.2,fn1,"a"); /* write TDT argument to file fn1 */
rc = system("load_cis "^^fn1^^" "^^fn2); /* execute load_cis.c & pass TDT arg */
delete(fn1); /* delete fn1, the TDT argument */
return(rc); /* return error codes to client */
}
if (parm.1 == "thor_purge") { /* 'load' TDT from client into Thor */
fn1 = tmpnam(); /* create filename & assign it to fn1 */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
list_file(parm.2,fn1,"a"); /* write TDT argument to file fn1 */
rc = system("purge_tdt "^^fn1^^" "^^fn2); /* execute load_cis.c & pass TDT arg */
delete(fn1); /* delete fn1, the TDT argument */
return(rc); /* return error codes to client */
}
else if (parm.1 == "smi_unique") { /* convert SMILES to a USMILES */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
#ifdef logging
log(logfile,"smi_unique:"^^list_curr(parm.2,0)^^", fn2: "^^fn2);
#endif
rc = system("unique_smile " /* execute unique_smile.c */
^^list_curr(parm.2,0)^^ /* pass SMILES argument from client */
" 1>"^^fn2^^" 2>&1"); /* return USMILES,MW,MF,CAS,ClogP */
#ifdef logging
log(logfile,"unique_smile returned "^^rc);
#endif
return(rc); /* return error codes to client */
}
else if (parm.1 == "smi_in_thor") { /* determine if SMILES is in Thor */
fn2 = tmpnam(); /* create filename & assign it to fn1 */
rc = system("is_smi_in_db " /* execute is_smi_in_db */
^^list_curr(parm.2,0)^^ /* pass SMILES argument from client */
" 1>"^^fn2^^" 2>&1"); /* return what??????????????????? */
return(rc); /* return error codes to client */
}
else if (parm.1 == "thor_getdat") { /* get USMILES,MW,MF,CAS,ClogP */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
/* parm.2 can be (smi 'c1...') or (wrno '999999') or ('cas 99-...')*/
#ifdef logging
log(logfile,"thor_getdat tmpnam = "^^fn2);
#endif
rc = system( "get_data_from_cis "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* return USMILES,MW,MF,CAS */
return(rc); /* return error codes to client */
}
else if (parm.1 == "thor_getlist") { /* submit struct list; get data list */
fn1 = tmpnam(); /* create filename & assign it to fn2 */
list_file(parm.2,fn1,"a");
fn2 = tmpnam(); /* create filename & assign it to fn2 */
rc = system( "wrno_list_from_cis " ^^fn1^^
" 1>"^^fn2^^" 2>&1"); /* > ascii file: WRNO,CAS,MF,MW,SMI */
system("echo '****' >> "^^fn2);
system("cat missing.wrno >> "^^fn2);
return(rc); /* return code to client */
}
else if (parm.1 == "minimer") { /* Run similarity search in Merlin */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
/* parm.2 can be (smi 'c1...') or (wrno '999999') or ('cas 99-...')*/
rc = system( "minimer "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* return hit list: SIM NDX,WRNO,SMI */
return(rc); /* return error codes to client */
}
else if (parm.1 == "merlin_search") { /* Run similarity search in Merlin */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
rc = system( "minimer_gen "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* return hit list: SIM NDX,WRNO,SMI */
return(rc); /* return error codes to client */
}
else if (parm.1 == "thor_search") { /* Run foreign search in Thor */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
/* parm.2 can be "'dbname' 'datatype' 'search_value'" */
rc = system( "search_foreign "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* return hit list: SMI WRNO MF MW CAS */
#ifdef logging
log(logfile,"rc: "^^rc);
while (true) {
log(logfile,list_curr(ll,0));
if (list_pos(ll) == list_next(ll)) break;
}
#endif
return(rc); /* return error codes to client */
}
else if (parm.1 == "merlin_open") { /* list chem dbs loaded into Merlin */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
rc = system("listmerlin "^^fn2); /* execute listmerlin sceipt,pass fname */
return(rc); /* return codes to client */
}
else if (parm.1 == "thor_open") { /* list Thor dbs that are online */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
rc = system("listthor "^^fn2); /* execute listmerlin sceipt,pass fname */
return(rc); /* return error codes to client */
}
else if (parm.1 == "chemcop_ping") { /* can client can talk to chemcop? */
return(0); /* return code to client */
}
else if (parm.1 == "merlin_ping") { /* is Merlin pool open & available? */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
/* parm.2 is name of merlin pool */
rc = system( "pingmerlin "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* parm.2= name of merlin db */
return(rc); /* return error codes to client */
}
else if (parm.1 == "thor_ping") { /* is Thor db open & available? */
fn2 = tmpnam(); /* create filename & assign it to fn2 */
/* parm.2 is name of Thor db */
rc = system( "pingthor "
^^list_curr(parm.2,0)^^
" 1>"^^fn2^^" 2>&1"); /* parm.2= name of merlin db */
return(rc); /* return error codes to client */
}
else if (parm.1 == "smi2mol") { /* convert SMILES to molfile */
fn1 = tmpnam();
fn2 = tmpnam();
list_file(parm.2,fn1,"a");
rc= system("smi2mol -s < "^^fn1^^" 1>"^^fn2^^" 2>&1");
/* system returns false on success, true on fail */
delete(fn1);
#ifdef logging
log(logfile,"smi2mol- smi_list: "^^list_curr(parm.2,0)^^", fn2: "^^fn2^^", rc: "^^rc);
#endif
return(rc); /* return error codes to client */
}
} /* end 'if (parm.0 == db_exec)' */
else if (parm.0 == db_open) { /* open ascii file on ChemServer */
if (parm.1 == "select results") { /* First parameter is list_open()*/
ll = list_open("2600",1); /* hard code 2600 for longest SMILES */
/* this row width limits the number of rows per fetch to fetch_buffer/2600 or about 3 */
list_mod(ll,1,1);
ll = list_merge(ll,list_open(fn2,10000),0);
list_mod(ll,0);
/* delete(fn2); delete fn2, file from SYS call */
return(ll); /* return data list from SYS call */
} /* end 'if parm.1= "select results...*/
if (parm.1 == "select tdt") { /* First parameter is list_open()*/
ll = list_open("/usr2/daylight/foreign_tdt.out",10000);
/* TDT file is fixed width @ 80 byte/rows so list_open(...) */
/* No need to set width to 2600 bytes as in "select results" */
delete(fn2); /* delete fn2, file from SYS call */
return(ll); /* return data list from SYS call */
} /* end 'if parm.1= "select results...*/
} /* end 'else if (parm.0 == db_open)..*/
else if (parm.0 == db_release) return(0);
else if (parm.0 == db_rollback) return(0);
return(1);
}