/****************************************************************/ /* xfshear 08.11.1996 */ /****************************************************************/ /* Short Description: */ /* */ /* Program for shearing of 2D MQMAS spectra of odd half */ /* integer quadrupolar nuclei. Data need to be aquired in */ /* States Mode */ /* Program used for shearing of ZQ-TROSY experiments */ /* like trosyzqgpphwg */ /****************************************************************/ /* Keywords: */ /* */ /* shear, odd half spin nuclei, multi quantum, mq, MQ */ /* ZQ-TROSY */ /****************************************************************/ /* Description/Usage: */ /* */ /* Program is used */ /* */ /* a) for 2D MQ experiments on nuclei with */ /* odd half integer spin for shearing-FT of 2D spectrum */ /* including 2DFT and referencing in F1 dimension */ /* according to delta(MQ)=delta(iso)+(p-R)delta(qis) */ /* It checks for the parameter "nucleus" (AMX) or "NUC1" */ /* (Avance) and sets the spin value accordingly. */ /* If the nucleus is not in the list it asks for the spin, */ /* too. Only most common nuclei are in the list. */ /* If the pulse program name matches mpxq, where */ /* x corresponds to the multiple quantum order of */ /* the experiment, then this is assumed, otherwise */ /* it is asked for by the program. */ /* Program asks if abs2 in F2 dimension is desired. */ /* If answered with yes, then a Hilbert transform */ /* is automatically done, which requires xwinnmr1.3 */ /* or later. In older versions, this command has to */ /* be eliminated from the program code. */ /* A F1 frequency shift in ppm is asked for to compensate */ /* for malchosen o1 setting. This value is stored and */ /* suggested for any repeated processing. */ /* */ /* b) for ZQ-TROSY experiments to eliminate the */ /* contribution of proton chemical shift in the */ /* F1 direction */ /****************************************************************/ /* Author(s): */ /* */ /* Name : Christian Fernandez */ /* Organisation : Universite de Lille, CNRS-801 */ /* Email : christian.fernandez@univ.lille.fr */ /* */ /* Name : Stefan Steuernagel */ /* Organisation : Bruker Analytik */ /* Email : stefan.steuernagel@bruker.de */ /****************************************************************/ /* Name Date Modification: */ /* */ /* ste 960201 created */ /* ste 980813 check xdim's and status sizes */ /* at right time */ /* ste 980813 XHT2 included after XF1 to */ /* allow f2 phase correction after */ /* processing */ /* ste 981101 close of input data files and */ /* "mv temp-file to 2rr" etc */ /* included */ /* ste 000105 XIF2 and XFB included after */ /* shearing to allow apodisation */ /* in F2, set-up to be done prior */ /* to execution of xfshear, all */ /* handling done by this program */ /* ber/ste 010909 handling for ZQ-TROSY experiment */ /* included, allows to use strip */ /* transformation in F2 only */ /* not strip-FT for MQMAS! */ /****************************************************************/ /* $Id: xfshear,v 1.9.2.1 2001/09/27 14:46:43 ste Exp $ */ #include <math.h> int parmode, si2, si1, outexpno, tempfile2rr, infile2rr, tempfile2ir, infile2ir, in2rr[4096], in2ir[4096], temp2rr[4096], temp2ir[4096], temp2rr2[4096], temp2ir2[4096], temp2rrB[4096], temp2irB[4096], temp2rrB2[4096], temp2irB2[4096], nbytes, sizeofint, nbytesread, xdim2, xdim1, loopcount4, sig, mq, nspin, wdw2, bcmod, phmod, stsr2, stsi1, stsi2; double sw1, sw2, ratio, ph, ph1, ph2, ph3, phc1, phc2, in0, sfo1, sfo12, sfo11, bf11, bf12; float Noise, spin, offset1, offset2, off2, off1, sr2, sr1, swh1; char inname2rr[PATH_LENGTH], tempname2rr[PATH_LENGTH], inname2ir[PATH_LENGTH], tempname2ir[PATH_LENGTH], outname[PATH_LENGTH], nucl[80], yes[20], pulprog[80], ti[80]; /* select current dataset ====================== */ GETCURDATA; (void) strcpy (yes, "yes"); /* is-it a 2D spectrum ? ===================== */ FETCHPAR("PARMODE", &parmode); if ( parmode != 1 ) { STOPMSG(" Not a 2D spectrum!"); } /* init some variables =================== */ FETCHPARS("PULPROG", pulprog); FETCHPARS("SFO1", &sfo1); FETCHPAR("WDW", &wdw2) STOREPAR("WDW", 0) /* shearing ratio calculation for quadrupolar nuclei set mq and spin to 1 for 1H ================================================= */ spin = 5./2.; mq = 3; FETCHPARS("NUC1", nucl) if (!strcmp(nucl, "off")) FETCHPARS ("NUCLEUS", nucl) if (!strcmp(nucl, "7Li")) spin = 1.5; else if (!strcmp(nucl, "11B")) spin = 1.5; else if (!strcmp(nucl, "17O")) spin = 2.5; else if (!strcmp(nucl, "23Na")) spin = 1.5; else if (!strcmp(nucl, "27Al")) spin = 2.5; else if (!strcmp(nucl, "35Cl")) spin = 1.5; else if (!strcmp(nucl, "39K")) spin = 1.5; else if (!strcmp(nucl, "45Sc")) spin = 3.5; else if (!strcmp(nucl, "45Sc")) spin = 3.5; else if (!strcmp(nucl, "51V")) spin = 3.5; else if (!strcmp(nucl, "55Mn")) spin = 2.5; else if (!strcmp(nucl, "63Cu")) spin = 1.5; else if (!strcmp(nucl, "65Cu")) spin = 1.5; else if (!strcmp(nucl, "69Ga")) spin = 1.5; else if (!strcmp(nucl, "71Ga")) spin = 1.5; else if (!strcmp(nucl, "85Rb")) spin = 2.5; else if (!strcmp(nucl, "87Rb")) spin = 1.5; else if (!strcmp(nucl, "93Nb")) spin = 4.5; else if (!strcmp(nucl, "121Sb")) spin = 2.5; else if (!strcmp(nucl, "1H")) spin = 1.0; else GETFLOAT(" Enter spin number : ", spin); nspin = (int) ceil( (double)(2*spin) ); if ( nspin == 3 ) { mq = -3; ratio = 7./9.; } else { if (!strncmp(pulprog, "mp3q", 4)) mq = 3; else if(!strncmp(pulprog, "mp5q", 4)) mq = 5; else if(!strncmp(pulprog, "mp7q", 4)) mq = 7; else if(!strncmp(pulprog, "mp9q", 4)) mq = 9; else if(!strcmp(pulprog, "trosyzqgpphwg")) mq = 1; else GETINT(" Enter the pQ order : ", mq); mq = (int) ceil( (double)mq ); if ( mq == nspin ) mq = -mq; if ( nspin == 5 && mq == -5) ratio = 25./12.; if ( nspin == 5 && mq == 3) ratio = 19./12.; if ( nspin == 7 && mq == -7) ratio = 161./45.; if ( nspin == 7 && mq == 5) ratio = 11./9.; if ( nspin == 7 && mq == 3) ratio = 101./45.; if ( nspin == 9 && mq == -9) ratio = 31./6.; if ( nspin == 9 && mq == 7) ratio = 7./18.; if ( nspin == 9 && mq == 5) ratio = 95./36.; if ( nspin == 9 && mq == 3) ratio = 91./36.; if ( mq == 1 ) ratio = -1.; }; /* ignore strip parameters in F1 for 1H spectra! ============================================= */ if ( mq == 1 ) { FETCHPAR1("STSI", &stsi1); STOREPAR1("STSR", 0); STOREPAR1("STSI", 0); if ( stsi1 != 0 ) Proc_err(0, "F1 Strip-FT not yet implemented, \nparameters disabled"); } /* ignore all strip parameters for MQMAS spectra ! =============================================== */ if ( mq != 1 ) { FETCHPAR("STSI", &stsi2); FETCHPAR1("STSI", &stsi1); STOREPAR("STSR", 0); STOREPAR("STSI", 0); STOREPAR1("STSR", 0); STOREPAR1("STSI", 0); if ( stsi2 != 0 || stsi1 != 0 ) Proc_err(0, "Strip-FT not yet implemented, \nparameters disabled"); } /* 1st FFT : acquisition must be done in STATES or echo/antiecho mode! and automatic baseline correction ? =============================================== */ if ( mq != 1 ) GETSTRING("Apply ABS2 ? : ", yes); STOREPAR1("MC2", 3); STOREPAR1S("MC2", 3); /* additional F1 shift ? ===================== */ f1 = 0.; FETCHPAR1S("NOISF1", &Noise); FETCHPARS("TI", ti); if ( !strcmp(ti,"shearing done") ) f1 = Noise; if ( mq != 1 ) GETFLOAT(" F1 shift in ppm ? : ", f1); /* calculate F2 transform ====================== */ XF2 if ( yes[0] == 'y' ) {ABS2 XHT2} /* get required status parameters after F2 transform ================================================= */ FETCHPARS("SW_p", &sw2); FETCHPARS("SI", &si2); FETCHPARS("STSR", &stsr2); FETCHPAR1S("SWH", &swh1); FETCHPAR1S("SI", &si1); FETCHPAR1S("XDIM", &xdim1); FETCHPARS("XDIM", &xdim2); sizeofint = sizeof(int); nbytes = sizeofint*xdim2*2; /* phase for shearing ================== */ ph1 = -2.*3.141529*ratio*sw2/swh1/(double)(si2); if ( mq < 0 ) ph1 = -ph1; d1 = fabs(ratio - (double)mq); if ( mq == 1 ) d1 = 1.0; sfo11 = d1*sfo1; /* additional F1 shift =================== */ ph2 = (double)f1; phc2 = -2.*3.141529*ph2*sfo11/(double)swh1; /* compensate for strip transformation of 1H spectra ================================================= */ if ( mq == 1 ) { ph3 = -ph1*stsr2; phc2 += ph3; } /* Open source file RR and IR ========================== */ (void)sprintf( inname2rr, "%s/data/%s/nmr/%s/%d/pdata/%d/2rr", disk, user, name, expno, procno); if ( (infile2rr = open(inname2rr,0)) == -1 ) { (void)sprintf(text, " I/O Error (Open) \n%s ", inname2rr); STOPMSG(text); } (void)sprintf( inname2ir, "%s/data/%s/nmr/%s/%d/pdata/%d/2ir", disk, user, name, expno, procno); if ( (infile2ir = open(inname2ir,0)) == -1 ) { (void)sprintf(text, " I/O Error (Open) \n%s ", inname2ir); STOPMSG(text); } /* Create temporary files : 2rrtemp et 2irtemp =========================================== */ (void)sprintf( tempname2rr, "%s/data/%s/nmr/%s/%d/2rrtemp", disk, user, name, expno); if ( (tempfile2rr = creat(tempname2rr,0664)) == -1 ) { (void)sprintf(text, " I/O Error (Create) \n%s ", tempname2rr); STOPMSG(text); } (void)sprintf( tempname2ir, "%s/data/%s/nmr/%s/%d/2irtemp", disk, user, name, expno); if ( (tempfile2ir = creat(tempname2ir,0664)) == -1 ) { (void)sprintf(text, " I/O Error (Create) \n%s ", tempname2ir); STOPMSG(text); } (void)sprintf(text, "shear : calculating"); Show_status(text); /* Read data in submatrix ====================== */ TIMES(si1/xdim1) TIMES2(si2/xdim2) TIMES3(xdim1/2) if ((nbytesread = read(infile2rr, in2rr, nbytes)) <= 0) /* Read 2 rows ! */ { (void)remove(tempname2rr); STOPMSG(" 2rr file corrupted! "); } if ((nbytesread = read(infile2ir, in2ir, nbytes)) <= 0) { (void)remove(tempname2ir); STOPMSG(" 2ir file corrupted! "); } /* Store Sx, I = 5/2, mq = 3 */ for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { temp2rr[loopcount4] = in2rr[loopcount4]; /* Re[Sx] */ temp2ir[loopcount4] = in2ir[loopcount4]; } /* Im[Sx] */ /* Store iSy, I = 5/2, mq = 3 */ for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { temp2rr2[loopcount4] = in2rr[loopcount4 + xdim2]; /* Re[Sy] */ temp2ir2[loopcount4] = in2ir[loopcount4 + xdim2]; } /* Im[Sy] */ /* combine Sx and iSy to create ============================ */ for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { /* echo, I = 5/2, mq = 3 */ /* Re[echo] = 0.5*(Re[Sx] - Im[Sy]) */ temp2rrB[loopcount4] = (temp2rr[loopcount4] - temp2ir2[loopcount4])/2; /* Im[echo] = 0.5*(Im[Sx] + Re[Sy]) */ temp2irB[loopcount4] = (temp2ir[loopcount4] + temp2rr2[loopcount4])/2; /* and antiecho, I = 5/2, mq = 3 */ /* Re[antiecho] = 0.5*(Re[Sx] + Im[Sy]) */ temp2rrB2[loopcount4] = (temp2rr[loopcount4] + temp2ir2[loopcount4])/2; /* Im[antiecho] = 0.5*(Im[Sx] - Re[Sy]) */ temp2irB2[loopcount4] = (temp2ir[loopcount4] - temp2rr2[loopcount4])/2; } /* perform shearing transformation =============================== */ i1 = loopcount3 + (loopcount1)*xdim1/2; for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { i2 = loopcount4 + (loopcount2)*xdim2; phc1 = ph1*(double)((i2 - si2/2)*i1); phc1 += phc2*(double)i1; /* Sheared echo, I = 5/2, mq = 3 */ /* Re[sheared-echo] = 0.5*(Re[echo]*cos phc1 + Im[echo]*sin phc1) */ in2rr[loopcount4] = (int)(((double)temp2rrB[loopcount4])*cos(phc1) + ((double)temp2irB[loopcount4])*sin(phc1))/2; /* Im[sheared-echo] = 0.5*(Im[echo]*cos phc1 - Re[echo]*sin phc1) */ in2ir[loopcount4] = (int)(((double)temp2irB[loopcount4])*cos(phc1) - ((double)temp2rrB[loopcount4])*sin(phc1))/2; /* Sheared antiecho, I = 5/2, mq = 3 */ /* Re[sheared-antiecho] = 0.5*(Re[antiecho]*cos phc1 - Im[antiecho]*sin phc1) */ in2rr[loopcount4 + xdim2] = (int)(((double)temp2rrB2[loopcount4])*cos(phc1) - ((double)temp2irB2[loopcount4])*sin(phc1))/2; /* Im[sheared-antiecho] = 0.5*(Im[antiecho]*cos phc1 + Re[antiecho]*sin phc1) */ in2ir[loopcount4 + xdim2] = (int)(((double)temp2irB2[loopcount4])*cos(phc1) + ((double)temp2rrB2[loopcount4])*sin(phc1))/2; } for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { /* Sheared Sx, I = 5/2, mq = 3 */ /* Re[sheared-Sx] = 0.5*(Re[sheared-echo] + Re[sheared-antiecho]) */ temp2rr[loopcount4] = 0.5*( in2rr[loopcount4] + in2rr[loopcount4 + xdim2]); /* Im[sheared-Sx] = 0.5*(Im[sheared-echo] + Im[sheared-antiecho]) */ temp2ir[loopcount4] = 0.5*( in2ir[loopcount4] + in2ir[loopcount4 + xdim2]); /* Sheared Sy, I = 5/2, mq = 3 */ /* -Im[sheared-Sy] = 0.5*(Re[sheared-echo] - Re[sheared-antiecho]) */ temp2irB[loopcount4] = 0.5*( in2rr[loopcount4] - in2rr[loopcount4 + xdim2]); /* Re[sheared-Sy] = 0.5*(Im[sheared-echo] - Im[sheared-antiecho]) */ temp2rrB[loopcount4] = 0.5*( in2ir[loopcount4] - in2ir[loopcount4 + xdim2]); } for (loopcount4 = 0; loopcount4 < xdim2; loopcount4++) { /** Real part for XF1 **/ in2rr[loopcount4] = temp2rr[loopcount4]; /*Re[sheared-Sx]*/ in2ir[loopcount4] = temp2ir[loopcount4]; /*Im[sheared-Sx]*/ /** Imaginary part for XF1 **/ in2rr[loopcount4 + xdim2] = temp2rrB[loopcount4];/*Re[sheared-Sy]*/ in2ir[loopcount4 + xdim2] = temp2irB2[loopcount4]; } /*Im[sheared-antiecho]*/ /* Save ==== */ write(tempfile2rr, in2rr, nbytesread); write(tempfile2ir, in2ir, nbytesread); END; /* loop3 */ END; /* loop2 */ END; /* loop1 */ close(tempfile2rr); close(tempfile2ir); close(infile2rr); close(infile2ir); /* Copy ==== */ (void)remove(inname2rr); if (rename(tempname2rr, inname2rr) != 0) Proc_err(1, "error %d", errno); (void)remove(inname2ir); if (rename(tempname2ir, inname2ir) != 0) Proc_err(1, "error %d", errno); (void)sprintf(text, "shear : finished"); Show_status(text); /* F1 Scaling for MQ MAS experiments ================================= */ if ( d1 != 1.0 ) { FETCHPARS("BF1", &bf12); FETCHPARS("SR", &sr2); bf11 = d1*bf12; sr1 = (float)(d1*sr2); STOREPAR1S("BF1", bf11); STOREPAR1("BF1", bf11); STOREPAR1S("SR", sr1); STOREPAR1("SR", sr1); STOREPAR1S("SFO1", sfo11); STOREPAR1("SFO1", sfo11); FETCHPAR1S("OFFSET", &offset1); offset1 = offset1 - ph2; STOREPAR1S("OFFSET", offset1); } /* store TI to recall shearing and shifting ======================================== */ STOREPARS("TI", "shearing done"); STOREPAR1S("NOISF1", f1); /* inverse F2 and subsequent F2+F1 transform ========================================= */ XHT2 XIF2 FETCHPAR("PH_mod", &phmod) STOREPAR("PH_mod", 0) STOREPAR("WDW", wdw2) FETCHPAR("BC_mod", &bcmod) STOREPAR("BC_mod", 0) XFB STOREPAR("PH_mod", phmod) STOREPAR("BC_mod", bcmod) /* Do not delete these two lines */ VIEWDATA QUITMSG(" Shearing-FT done!")
Before executing the AU program xfshear, the first spectrum from the SER file should be phased like a positive amplitude absorption spectrum.