int main(int argc,char *argv[]) { static char *desc[] = { "do_dssp ", "reads a trajectory file and computes the secondary structure for", "each time frame ", "calling the dssp program. If you do not have the dssp program,", "get it. do_dssp assumes that the dssp executable is", "/usr/local/bin/dssp. If this is not the case, then you should", "set an environment variable [BB]DSSP[bb] pointing to the dssp", "executable, e.g.: [PAR]", "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]", "The structure assignment for each residue and time is written to an", "[TT].xpm[tt] matrix file. This file can be visualized with for instance", "[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].", "The number of residues with each secondary structure type and the", "total secondary structure ([TT]-sss[tt]) count as a function of", "time are also written to file ([TT]-sc[tt]).[PAR]", "Solvent accessible surface (SAS) per residue can be calculated, both in", "absolute values (A^2) and in fractions of the maximal accessible", "surface of a residue. The maximal accessible surface is defined as", "the accessible surface of a residue in a chain of glycines.", "[BB]Note[bb] that the program [TT]g_sas[tt] can also compute SAS", "and that is more efficient.[PAR]", "Finally, this program can dump the secondary structure in a special file", "[TT]ssdump.dat[tt] for usage in the program [TT]g_chi[tt]. Together", "these two programs can be used to analyze dihedral properties as a", "function of secondary structure type." }; static bool bVerbose; static char *ss_string="HEBT"; t_pargs pa[] = { { "-v", FALSE, etBOOL, {&bVerbose}, "HIDDENGenerate miles of useless information" }, { "-sss", FALSE, etSTR, {&ss_string}, "Secondary structures for structure count"} }; int status; FILE *tapein; FILE *ss,*acc,*fTArea,*tmpf; char *fnSCount,*fnArea,*fnTArea,*fnAArea; char *leg[] = { "Phobic", "Phylic" }; t_topology top; int ePBC; t_atoms *atoms; t_matrix mat; int nres,nr0,naccr; bool *bPhbres,bDoAccSurf; real t; int i,j,natoms,nframe=0; matrix box; int gnx; char *grpnm,*ss_str; atom_id *index; rvec *xp,*x; int *average_area; real **accr,*av_area, *norm_av_area; char pdbfile[32],tmpfile[32],title[256]; char dssp[256],*dptr; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-ssdump", "ssdump", ffOPTWR }, { efMAP, "-map", "ss", ffLIBRD }, { efXPM, "-o", "ss", ffWRITE }, { efXVG, "-sc", "scount", ffWRITE }, { efXPM, "-a", "area", ffOPTWR }, { efXVG, "-ta", "totarea", ffOPTWR }, { efXVG, "-aa", "averarea",ffOPTWR } }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT | PCA_BE_NICE , NFILE,fnm, asize(pa),pa, asize(desc),desc,0,NULL); fnSCount= opt2fn("-sc",NFILE,fnm); fnArea = opt2fn_null("-a", NFILE,fnm); fnTArea = opt2fn_null("-ta",NFILE,fnm); fnAArea = opt2fn_null("-aa",NFILE,fnm); bDoAccSurf=(fnArea || fnTArea || fnAArea); read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xp,NULL,box,FALSE); atoms=&(top.atoms); check_oo(atoms); bPhbres=bPhobics(atoms); get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpnm); nres=0; nr0=-1; for(i=0; (i<gnx); i++) { if (atoms->atom[index[i]].resnr != nr0) { nr0=atoms->atom[index[i]].resnr; nres++; } } fprintf(stderr,"There are %d residues in your selected group\n",nres); strcpy(pdbfile,"ddXXXXXX"); gmx_tmpnam(pdbfile); if ((tmpf = fopen(pdbfile,"w")) == NULL) { sprintf(pdbfile,"%ctmp%cfilterXXXXXX",DIR_SEPARATOR,DIR_SEPARATOR); gmx_tmpnam(pdbfile); if ((tmpf = fopen(pdbfile,"w")) == NULL) gmx_fatal(FARGS,"Can not open tmp file %s",pdbfile); } else fclose(tmpf); strcpy(tmpfile,"ddXXXXXX"); gmx_tmpnam(tmpfile); if ((tmpf = fopen(tmpfile,"w")) == NULL) { sprintf(tmpfile,"%ctmp%cfilterXXXXXX",DIR_SEPARATOR,DIR_SEPARATOR); gmx_tmpnam(tmpfile); if ((tmpf = fopen(tmpfile,"w")) == NULL) gmx_fatal(FARGS,"Can not open tmp file %s",tmpfile); } else fclose(tmpf); if ((dptr=getenv("DSSP")) == NULL) dptr="/usr/local/bin/dssp"; if (!fexist(dptr)) gmx_fatal(FARGS,"DSSP executable (%s) does not exist (use setenv DSSP)", dptr); sprintf(dssp,"%s %s %s %s > /dev/null %s", dptr,bDoAccSurf?"":"-na",pdbfile,tmpfile,bVerbose?"":"2> /dev/null"); if (bVerbose) fprintf(stderr,"dssp cmd='%s'\n",dssp); if (fnTArea) { fTArea=xvgropen(fnTArea,"Solvent Accessible Surface Area", xvgr_tlabel(),"Area (nm\\S2\\N)"); xvgr_legend(fTArea,2,leg); } else fTArea=NULL; mat.map=NULL; mat.nmap=getcmap(libopen(opt2fn("-map",NFILE,fnm)), opt2fn("-map",NFILE,fnm),&(mat.map)); natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); if (natoms > atoms->nr) gmx_fatal(FARGS,"\nTrajectory does not match topology!"); if (gnx > natoms) gmx_fatal(FARGS,"\nTrajectory does not match selected group!"); snew(average_area,atoms->nres+10); snew(av_area,atoms->nres+10); snew(norm_av_area,atoms->nres+10); accr=NULL; naccr=0; do { t = convert_time(t); if (nframe>=naccr) { naccr+=10; srenew(accr,naccr); for(i=naccr-10; i<naccr; i++) snew(accr[i],atoms->nres+10); } rm_pbc(&(top.idef),ePBC,natoms,box,x,x); tapein=ffopen(pdbfile,"w"); write_pdbfile_indexed(tapein,NULL,atoms,x,ePBC,box,0,-1,gnx,index); fclose(tapein); #ifdef GMX_NO_SYSTEM printf("Warning-- No calls to system(3) supported on this platform."); printf("Warning-- Skipping execution of 'system(\"%s\")'.", dssp); exit(1); #else if(0 != system(dssp)) { gmx_fatal(FARGS,"Failed to execute command: %s",dssp); } #endif strip_dssp(tmpfile,nres,bPhbres,t, accr[nframe],fTArea,&mat,average_area); remove(tmpfile); remove(pdbfile); nframe++; } while(read_next_x(status,&t,natoms,x,box)); fprintf(stderr,"\n"); close_trj(status); if (fTArea) ffclose(fTArea); prune_ss_legend(&mat); ss=opt2FILE("-o",NFILE,fnm,"w"); write_xpm_m(ss,mat); ffclose(ss); if (opt2bSet("-ssdump",NFILE,fnm)) { snew(ss_str,nres+1); for(i=0; (i<nres); i++) ss_str[i] = mat.map[mat.matrix[0][i]].code.c1; ss_str[i] = '\0'; ss = opt2FILE("-ssdump",NFILE,fnm,"w"); fprintf(ss,"%d\n%s\n",nres,ss_str); fclose(ss); sfree(ss_str); } analyse_ss(fnSCount,&mat,ss_string); if (bDoAccSurf) { write_sas_mat(fnArea,accr,nframe,nres,&mat); for(i=0; i<atoms->nres; i++) av_area[i] = (average_area[i] / (real)nframe); norm_acc(atoms, nres, av_area, norm_av_area); if (fnAArea) { acc=xvgropen(fnAArea,"Average Accessible Area", "Residue","A\\S2"); for(i=0; (i<nres); i++) fprintf(acc,"%5d %10g %10g\n",i+1,av_area[i], norm_av_area[i]); ffclose(acc); } } view_all(NFILE, fnm); thanx(stderr); return 0; }
int gmx_do_dssp(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] ", "reads a trajectory file and computes the secondary structure for", "each time frame ", "calling the dssp program. If you do not have the dssp program,", "get it from http://swift.cmbi.ru.nl/gv/dssp. [THISMODULE] assumes ", "that the dssp executable is located in ", "[TT]/usr/local/bin/dssp[tt]. If this is not the case, then you should", "set an environment variable [TT]DSSP[tt] pointing to the dssp", "executable, e.g.: [PAR]", "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]", "Since version 2.0.0, dssp is invoked with a syntax that differs", "from earlier versions. If you have an older version of dssp,", "use the [TT]-ver[tt] option to direct do_dssp to use the older syntax.", "By default, do_dssp uses the syntax introduced with version 2.0.0.", "Even newer versions (which at the time of writing are not yet released)", "are assumed to have the same syntax as 2.0.0.[PAR]", "The structure assignment for each residue and time is written to an", "[TT].xpm[tt] matrix file. This file can be visualized with for instance", "[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].", "Individual chains are separated by light grey lines in the [TT].xpm[tt] and", "postscript files.", "The number of residues with each secondary structure type and the", "total secondary structure ([TT]-sss[tt]) count as a function of", "time are also written to file ([TT]-sc[tt]).[PAR]", "Solvent accessible surface (SAS) per residue can be calculated, both in", "absolute values (A^2) and in fractions of the maximal accessible", "surface of a residue. The maximal accessible surface is defined as", "the accessible surface of a residue in a chain of glycines.", "[BB]Note[bb] that the program [gmx-sas] can also compute SAS", "and that is more efficient.[PAR]", "Finally, this program can dump the secondary structure in a special file", "[TT]ssdump.dat[tt] for usage in the program [gmx-chi]. Together", "these two programs can be used to analyze dihedral properties as a", "function of secondary structure type." }; static gmx_bool bVerbose; static const char *ss_string = "HEBT"; static int dsspVersion = 2; t_pargs pa[] = { { "-v", FALSE, etBOOL, {&bVerbose}, "HIDDENGenerate miles of useless information" }, { "-sss", FALSE, etSTR, {&ss_string}, "Secondary structures for structure count"}, { "-ver", FALSE, etINT, {&dsspVersion}, "DSSP major version. Syntax changed with version 2"} }; t_trxstatus *status; FILE *tapein; FILE *ss, *acc, *fTArea, *tmpf; const char *fnSCount, *fnArea, *fnTArea, *fnAArea; const char *leg[] = { "Phobic", "Phylic" }; t_topology top; int ePBC; t_atoms *atoms; t_matrix mat; int nres, nr0, naccr, nres_plus_separators; gmx_bool *bPhbres, bDoAccSurf; real t; int i, j, natoms, nframe = 0; matrix box = {{0}}; int gnx; char *grpnm, *ss_str; atom_id *index; rvec *xp, *x; int *average_area; real **accr, *accr_ptr = NULL, *av_area, *norm_av_area; char pdbfile[32], tmpfile[32], title[256]; char dssp[256]; const char *dptr; output_env_t oenv; gmx_rmpbc_t gpbc = NULL; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-ssdump", "ssdump", ffOPTWR }, { efMAP, "-map", "ss", ffLIBRD }, { efXPM, "-o", "ss", ffWRITE }, { efXVG, "-sc", "scount", ffWRITE }, { efXPM, "-a", "area", ffOPTWR }, { efXVG, "-ta", "totarea", ffOPTWR }, { efXVG, "-aa", "averarea", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } fnSCount = opt2fn("-sc", NFILE, fnm); fnArea = opt2fn_null("-a", NFILE, fnm); fnTArea = opt2fn_null("-ta", NFILE, fnm); fnAArea = opt2fn_null("-aa", NFILE, fnm); bDoAccSurf = (fnArea || fnTArea || fnAArea); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xp, NULL, box, FALSE); atoms = &(top.atoms); check_oo(atoms); bPhbres = bPhobics(atoms); get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpnm); nres = 0; nr0 = -1; for (i = 0; (i < gnx); i++) { if (atoms->atom[index[i]].resind != nr0) { nr0 = atoms->atom[index[i]].resind; nres++; } } fprintf(stderr, "There are %d residues in your selected group\n", nres); strcpy(pdbfile, "ddXXXXXX"); gmx_tmpnam(pdbfile); if ((tmpf = fopen(pdbfile, "w")) == NULL) { sprintf(pdbfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR); gmx_tmpnam(pdbfile); if ((tmpf = fopen(pdbfile, "w")) == NULL) { gmx_fatal(FARGS, "Can not open tmp file %s", pdbfile); } } else { fclose(tmpf); } strcpy(tmpfile, "ddXXXXXX"); gmx_tmpnam(tmpfile); if ((tmpf = fopen(tmpfile, "w")) == NULL) { sprintf(tmpfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR); gmx_tmpnam(tmpfile); if ((tmpf = fopen(tmpfile, "w")) == NULL) { gmx_fatal(FARGS, "Can not open tmp file %s", tmpfile); } } else { fclose(tmpf); } if ((dptr = getenv("DSSP")) == NULL) { dptr = "/usr/local/bin/dssp"; } if (!gmx_fexist(dptr)) { gmx_fatal(FARGS, "DSSP executable (%s) does not exist (use setenv DSSP)", dptr); } if (dsspVersion >= 2) { if (dsspVersion > 2) { printf("\nWARNING: You use DSSP version %d, which is not explicitly\nsupported by do_dssp. Assuming version 2 syntax.\n\n", dsspVersion); } sprintf(dssp, "%s -i %s -o %s > /dev/null %s", dptr, pdbfile, tmpfile, bVerbose ? "" : "2> /dev/null"); } else { sprintf(dssp, "%s %s %s %s > /dev/null %s", dptr, bDoAccSurf ? "" : "-na", pdbfile, tmpfile, bVerbose ? "" : "2> /dev/null"); } fprintf(stderr, "dssp cmd='%s'\n", dssp); if (fnTArea) { fTArea = xvgropen(fnTArea, "Solvent Accessible Surface Area", output_env_get_xvgr_tlabel(oenv), "Area (nm\\S2\\N)", oenv); xvgr_legend(fTArea, 2, leg, oenv); } else { fTArea = NULL; } mat.map = NULL; mat.nmap = readcmap(opt2fn("-map", NFILE, fnm), &(mat.map)); natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); if (natoms > atoms->nr) { gmx_fatal(FARGS, "\nTrajectory does not match topology!"); } if (gnx > natoms) { gmx_fatal(FARGS, "\nTrajectory does not match selected group!"); } snew(average_area, atoms->nres); snew(av_area, atoms->nres); snew(norm_av_area, atoms->nres); accr = NULL; naccr = 0; gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms); do { t = output_env_conv_time(oenv, t); if (bDoAccSurf && nframe >= naccr) { naccr += 10; srenew(accr, naccr); for (i = naccr-10; i < naccr; i++) { snew(accr[i], 2*atoms->nres-1); } } gmx_rmpbc(gpbc, natoms, box, x); tapein = gmx_ffopen(pdbfile, "w"); write_pdbfile_indexed(tapein, NULL, atoms, x, ePBC, box, ' ', -1, gnx, index, NULL, TRUE); gmx_ffclose(tapein); if (0 != system(dssp)) { gmx_fatal(FARGS, "Failed to execute command: %s\n", "Try specifying your dssp version with the -ver option.", dssp); } /* strip_dssp returns the number of lines found in the dssp file, i.e. * the number of residues plus the separator lines */ if (bDoAccSurf) { accr_ptr = accr[nframe]; } nres_plus_separators = strip_dssp(tmpfile, nres, bPhbres, t, accr_ptr, fTArea, &mat, average_area, oenv); remove(tmpfile); remove(pdbfile); nframe++; } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); close_trj(status); if (fTArea) { xvgrclose(fTArea); } gmx_rmpbc_done(gpbc); prune_ss_legend(&mat); ss = opt2FILE("-o", NFILE, fnm, "w"); mat.flags = 0; write_xpm_m(ss, mat); gmx_ffclose(ss); if (opt2bSet("-ssdump", NFILE, fnm)) { ss = opt2FILE("-ssdump", NFILE, fnm, "w"); snew(ss_str, nres+1); fprintf(ss, "%d\n", nres); for (j = 0; j < mat.nx; j++) { for (i = 0; (i < mat.ny); i++) { ss_str[i] = mat.map[mat.matrix[j][i]].code.c1; } ss_str[i] = '\0'; fprintf(ss, "%s\n", ss_str); } gmx_ffclose(ss); sfree(ss_str); } analyse_ss(fnSCount, &mat, ss_string, oenv); if (bDoAccSurf) { write_sas_mat(fnArea, accr, nframe, nres_plus_separators, &mat); for (i = 0; i < atoms->nres; i++) { av_area[i] = (average_area[i] / (real)nframe); } norm_acc(atoms, nres, av_area, norm_av_area); if (fnAArea) { acc = xvgropen(fnAArea, "Average Accessible Area", "Residue", "A\\S2", oenv); for (i = 0; (i < nres); i++) { fprintf(acc, "%5d %10g %10g\n", i+1, av_area[i], norm_av_area[i]); } xvgrclose(acc); } } view_all(oenv, NFILE, fnm); return 0; }
double PZStability::eval(const arma::vec & x, int mode) { double focktol=ROUGHTOL; // Rotation cutoff double rotcut=10*DBL_EPSILON; if(restr) { rscf_t tmp(rsol); // List of occupieds to check std::vector<size_t> chkorb; if(mode==-1 || mode == 0) { for(size_t o=0;o<oa;o++) chkorb.push_back(o); } // Get rotation matrix arma::cx_mat Rov; if(cancheck) { // ov rotation matrix Rov=ov_rotation(x,false); // Get list of changed occupied orbitals if(mode==1) chkorb=check_ov(Rov.submat(0,oa,oa-1,Rov.n_cols-1),rotcut); } // Do we need to do the reference part? if(chkorb.size() || mode==-1 || mode==0) { if(cancheck) { // Rotate orbitals tmp.cC=tmp.cC*Rov; // Update density matrix tmp.P=2.0*arma::real(tmp.cC.cols(0,oa-1)*arma::trans(tmp.cC.cols(0,oa-1))); } // Dummy occupation vector std::vector<double> occa(oa,2.0); // Build global Fock operator solverp->Fock_RDFT(tmp,occa,method,grid,nlgrid,focktol); // Update reference energy if(mode==-1) ref_E0=tmp.en.E; } else if(mode==1) { // No, we don't. Set energy tmp.en.E=ref_E0; } else { ERROR_INFO(); throw std::runtime_error("Shouldn't be here!\n"); } // Get oo rotation arma::cx_mat Roo; if(oocheck) { Roo=oo_rotation(x,false); if(mode==1) check_oo(chkorb,Roo,rotcut); } else Roo.eye(oa,oa); // Orbital SI energies arma::vec Eo(ref_Eo); // Do we need to do anything for the oo part? if(chkorb.size() || mode == 0 || mode == -1) { // Collect list of changed occupied orbitals arma::uvec orblist(arma::sort(arma::conv_to<arma::uvec>::from(chkorb))); // Transformed oo block arma::cx_mat Ct=tmp.cC.cols(0,oa-1)*Roo; // Dummy matrix arma::cx_mat Rdum=arma::eye(orblist.n_elem,orblist.n_elem)*COMPLEX1; // Build the SI part std::vector<arma::cx_mat> Forb; arma::vec Eorb; solverp->PZSIC_Fock(Forb,Eorb,Ct.cols(orblist),Rdum,method,grid,nlgrid,false); if(mode==1) { for(size_t i=0;i<orblist.n_elem;i++) Eo(orblist(i))=Eorb(i); } else { Eo=Eorb; if(mode==-1) // Update reference ref_Eo=Eorb; } } // Account for spin return tmp.en.E - 2.0*arma::sum(Eo); } else { uscf_t tmp(usol); // List of occupieds to check std::vector<size_t> chkorba, chkorbb; if(mode==-1 || mode==0) { for(size_t o=0;o<oa;o++) chkorba.push_back(o); for(size_t o=0;o<ob;o++) chkorbb.push_back(o); } // Get rotation matrix arma::cx_mat Rova, Rovb; if(cancheck) { // ov rotation matrix Rova=ov_rotation(x,false); Rovb=ov_rotation(x,true); // Get list of changed occupied orbitals if(mode==1) { chkorba=check_ov(Rova.submat(0,oa,oa-1,oa+va-1),rotcut); chkorbb=check_ov(Rovb.submat(0,ob,ob-1,ob+vb-1),rotcut); } } // Do we need to do the reference part? if(chkorba.size() || chkorbb.size() || mode==-1 || mode==0) { if(cancheck) { // Rotate orbitals tmp.cCa=tmp.cCa*Rova; tmp.cCb=tmp.cCb*Rovb; // Update density matrix tmp.Pa=arma::real(tmp.cCa.cols(0,oa-1)*arma::trans(tmp.cCa.cols(0,oa-1))); tmp.Pb=arma::real(tmp.cCb.cols(0,ob-1)*arma::trans(tmp.cCb.cols(0,ob-1))); tmp.P=tmp.Pa+tmp.Pb; } // Dummy occupation vector std::vector<double> occa(oa,1.0); std::vector<double> occb(ob,1.0); // Build global Fock operator solverp->Fock_UDFT(tmp,occa,occb,method,grid,nlgrid,focktol); // Update reference energy if(mode==-1) ref_E0=tmp.en.E; } else if(mode==1) { // No, we don't. Set energy tmp.en.E=ref_E0; } else { ERROR_INFO(); throw std::runtime_error("Shouldn't be here!\n"); } // Get oo rotation arma::cx_mat Rooa, Roob; if(oocheck) { Rooa=oo_rotation(x,false); Roob=oo_rotation(x,true); if(mode==1) { check_oo(chkorba,Rooa,rotcut); check_oo(chkorbb,Roob,rotcut); } } else { Rooa.eye(oa,oa); Roob.eye(ob,ob); } // Orbital SI energies arma::vec Eoa(ref_Eoa), Eob(ref_Eob); // Do we need to do anything for the oo part? if(chkorba.size() || mode == 0 || mode == -1) { // Collect list of changed occupied orbitals arma::uvec orblist(arma::sort(arma::conv_to<arma::uvec>::from(chkorba))); // Transformed oo block arma::cx_mat Ct=tmp.cCa.cols(0,oa-1)*Rooa; // Dummy matrix arma::cx_mat Rdum=arma::eye(orblist.n_elem,orblist.n_elem)*COMPLEX1; // Build the SI part std::vector<arma::cx_mat> Forb; arma::vec Eorb; solverp->PZSIC_Fock(Forb,Eorb,Ct.cols(orblist),Rdum,method,grid,nlgrid,false); // Collect energies if(mode==1) { for(size_t i=0;i<orblist.n_elem;i++) Eoa(orblist(i))=Eorb(i); } else { Eoa=Eorb; if(mode==-1) // Update reference ref_Eoa=Eorb; } } if(chkorbb.size() || mode == 0 || mode == -1) { // Collect list of changed occupied orbitals arma::uvec orblist(arma::sort(arma::conv_to<arma::uvec>::from(chkorbb))); // Transformed oo block arma::cx_mat Ct=tmp.cCb.cols(0,ob-1)*Roob; // Dummy matrix arma::cx_mat Rdum=arma::eye(orblist.n_elem,orblist.n_elem)*COMPLEX1; // Build the SI part std::vector<arma::cx_mat> Forb; arma::vec Eorb; solverp->PZSIC_Fock(Forb,Eorb,Ct.cols(orblist),Rdum,method,grid,nlgrid,false); // Collect energies if(mode==1) { for(size_t i=0;i<orblist.n_elem;i++) Eob(orblist(i))=Eorb(i); } else { Eob=Eorb; if(mode==-1) // Update reference ref_Eob=Eorb; } } // Result is return tmp.en.E-arma::sum(Eoa)-arma::sum(Eob); } }