static void scripts_version_read(scripts_version_t v) { GKeyFile *f = g_key_file_new(); v->configuration[0]= '\0'; v->version[0]= '\0'; if (g_key_file_load_from_file(f, VERSIONFILE, G_KEY_FILE_NONE, NULL)==TRUE) { kval(f, "configuration", v->configuration, sizeof(v->configuration)); kval(f, "version", v->version, sizeof(v->version)); } g_key_file_free(f); }
// Interpolate table (linearly) to some specific k: DComplex kTable::kval(double kx, double ky) const { kx /= dk; ky /= dk; int i = static_cast<int> (floor(ky)); double fy = ky-i; int j = static_cast<int> (floor(kx)); double fx = kx-j; return (1-fx)*( (1-fy)*kval(i,j) + fy*kval(i+1,j)) + fx*( (1-fy)*kval(i,j+1) + fy*kval(i+1,j+1)); }
/* * alphac_cutoff - returns attenuation for a cutoff wg */ double rectwaveguide::alphac_cutoff () { double acc; acc = sqrt (pow (kc(1,0), 2.0) - pow (kval (), 2.0)); acc = 20 * log10 (exp (1.0)) * acc; return acc; }
/* * synthesize - synthesis function */ void rectwaveguide::synthesize () { double lambda_g, k, beta; /* Get and assign substrate parameters */ get_rectwaveguide_sub(); /* Get and assign component parameters */ get_rectwaveguide_comp(); /* Get and assign electrical parameters */ get_rectwaveguide_elec(); /* Get and assign physical parameters */ get_rectwaveguide_phys(); if (isSelected ("b")) { /* solve for b */ b = Z0 * a * sqrt(1.0 - pow((fc(1,0)/f),2.0))/ (2. * ZF0); setProperty ("b", b, UNIT_LENGTH, LENGTH_M); } else if (isSelected ("a")) { /* solve for a */ a = sqrt(pow((2.0 * ZF0 * b/Z0), 2.0) + pow((C0/(2.0 * f)),2.0)); setProperty ("a", a, UNIT_LENGTH, LENGTH_M); } k = kval (); beta = sqrt(pow(k,2.) - pow(kc(1,0),2.0)); lambda_g = (2. * M_PI)/beta; l = (ang_l * lambda_g)/(2.0 * M_PI); /* in m */ setProperty ("L", l, UNIT_LENGTH, LENGTH_M); if (kc(1,0) <= k) { /*propagating modes */ beta = sqrt(pow(k,2.) - pow(kc(1,0),2.0)); lambda_g = (2. * M_PI)/beta; atten_cond = alphac () * l; atten_dielectric = alphad () * l; er_eff = (1.0 - pow((fc(1,0)/f),2.0)); } else { /*evanascent modes */ Z0 = 0; ang_l = 0; er_eff = 0; atten_dielectric = 0.0; atten_cond = alphac_cutoff () * l; } show_results (); }
/* * returns attenuation due to dielectric losses */ double rectwaveguide::alphad() { double k, beta; double ad; k = kval (); beta = sqrt (pow (k, 2.0) - pow (kc (1,0), 2.0)); ad = (pow (k, 2.0) * tand) / (2.0 * beta); ad = ad * 20.0 * log10 (exp (1.0)); /* convert from Np/m to db/m */ return ad; }
int rapMapSAIndex(int argc, char* argv[]) { std::cerr << "RapMap Indexer\n"; TCLAP::CmdLine cmd("RapMap Indexer"); TCLAP::ValueArg<std::string> transcripts("t", "transcripts", "The transcript file to be indexed", true, "", "path"); TCLAP::ValueArg<std::string> index("i", "index", "The location where the index should be written", true, "", "path"); TCLAP::ValueArg<uint32_t> kval("k", "klen", "The length of k-mer to index", false, 31, "positive integer less than 32"); cmd.add(transcripts); cmd.add(index); cmd.add(kval); cmd.parse(argc, argv); // stupid parsing for now std::string transcriptFile(transcripts.getValue()); std::vector<std::string> transcriptFiles({ transcriptFile }); uint32_t k = kval.getValue(); if (k % 2 == 0) { std::cerr << "Error: k must be an odd value, you chose " << k << '\n'; std::exit(1); } else if (k > 31) { std::cerr << "Error: k must not be larger than 31, you chose " << k << '\n'; std::exit(1); } rapmap::utils::my_mer::k(k); std::string indexDir = index.getValue(); if (indexDir.back() != '/') { indexDir += '/'; } bool dirExists = rapmap::fs::DirExists(indexDir.c_str()); bool dirIsFile = rapmap::fs::FileExists(indexDir.c_str()); if (dirIsFile) { std::cerr << "The requested index directory already exists as a file."; std::exit(1); } if (!dirExists) { rapmap::fs::MakeDir(indexDir.c_str()); } size_t maxReadGroup{1000}; // Number of reads in each "job" size_t concurrentFile{2}; // Number of files to read simultaneously size_t numThreads{2}; stream_manager streams(transcriptFiles.begin(), transcriptFiles.end(), concurrentFile); std::unique_ptr<single_parser> transcriptParserPtr{nullptr}; transcriptParserPtr.reset(new single_parser(4 * numThreads, maxReadGroup, concurrentFile, streams)); std::mutex iomutex; indexTranscriptsSA(transcriptParserPtr.get(), indexDir, iomutex); return 0; }
double theta_est(int k_obs, int n) { /* Estimates theta = 4N*mu using formula 9.26 in Ewens' book */ double kval(double theta, int n); double xlow, xhigh, xmid; double eps; eps = 0.00001; xlow = 0.1; while (kval(xlow, n) > k_obs) xlow /= 10.0; xhigh = 10.0; while (kval(xhigh, n) < k_obs) xhigh *= 10.0; while ((xhigh - xlow) > eps) { xmid = (xhigh + xlow) / 2.0; if (kval(xmid, n) > k_obs) xhigh = xmid; else xlow = xmid; } return xmid; } /* end, theta_est */
/* * alphac - returns attenuation due to conductor losses for all propagating * modes in the waveguide */ double rectwaveguide::alphac () { double Rs, k, f_c; double ac; short m, n, mmax, nmax; Rs = sqrt ((M_PI * f * mur * MU0) / sigma); k = kval (); ac = 0.0; mmax = (int) floor (f / fc (1,0)); nmax = mmax; /* below from Ramo, Whinnery & Van Duzer */ /* TE(m,n) modes */ for (n = 0; n<= nmax; n++){ for (m = 1; m <= mmax; m++){ f_c = fc(m, n); if (f > f_c) { switch (n) { case 0: ac += (Rs/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) * (1.0 + ((2 * b/a)*pow((f_c/f),2.0))); break; default: ac += ((2. * Rs)/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) * (((1. + (b/a))*pow((f_c/f),2.0)) + ((1. - pow((f_c/f),2.0)) * (((b/a)*(((b/a)*pow(m,2.)) + pow(n,2.)))/ (pow((b*m/a),2.0) + pow(n,2.0))))); break; } } } } /* TM(m,n) modes */ for (n = 1; n<= nmax; n++) { for (m = 1; m<= mmax; m++) { f_c = fc(m, n); if (f > f_c) { ac += ((2. * Rs)/(b * ZF0 * sqrt(1.0 - pow((f_c/f),2.0)))) * (((pow(m,2.0)*pow((b/a),3.0)) + pow(n,2.))/ ((pow((m*b/a),2.)) + pow(n,2.0))); } } } ac = ac * 20.0 * log10 (exp (1.0)); /* convert from Np/m to db/m */ return ac; }
/* * analyze - analysis function */ void rectwaveguide::analyze () { double lambda_g; double k; double beta; /* Get and assign substrate parameters */ get_rectwaveguide_sub(); /* Get and assign component parameters */ get_rectwaveguide_comp(); /* Get and assign physical parameters */ get_rectwaveguide_phys(); k = kval (); if (kc (1,0) <= k) { /* propagating modes */ beta = sqrt (pow (k, 2.0) - pow (kc (1,0), 2.0)); lambda_g = 2.0 * M_PI / beta; /* Z0 = (k * ZF0) / beta; */ Z0 = k * ZF0 / beta; /* calculate electrical angle */ lambda_g = 2.0 * M_PI / beta; ang_l = 2.0 * M_PI * l / lambda_g; /* in radians */ atten_cond = alphac () * l; atten_dielectric = alphad () * l; er_eff = (1.0 - pow ((fc (1,0) / f), 2.0)); } else { /* evanascent modes */ Z0 = 0; ang_l = 0; er_eff = 0; atten_dielectric = 0.0; atten_cond = alphac_cutoff () * l; } setProperty ("Z0", Z0, UNIT_RES, RES_OHM); setProperty ("Ang_l", ang_l, UNIT_ANG, ANG_RAD); show_results (); }
// Interpolate table to some specific k. We WILL wrap the KTable to cover // entire interpolation kernel: std::complex<double> KTable::interpolate( double kx, double ky, const Interpolant2d& interp) const { dbg<<"Start KTable interpolate at "<<kx<<','<<ky<<std::endl; dbg<<"N = "<<_N<<std::endl; const int No2 = _N>>1; // == _N/2 dbg<<"interp xrage = "<<interp.xrange()<<std::endl; kx /= _dk; ky /= _dk; int ixMin, ixMax, iyMin, iyMax; if ( interp.isExactAtNodes() && std::abs(kx - std::floor(kx+0.01)) < 10.*std::numeric_limits<double>::epsilon()) { // x coord lies right on integer value, no interpolation in x direction ixMin = int(std::floor(kx+0.01)) % _N; if (ixMin < -No2) ixMin += _N; if (ixMin >= No2) ixMin -= _N; ixMax = ixMin; } else if (interp.xrange() >= No2) { // use all the elements in row: ixMin = -No2; ixMax = No2-1; } else { // Put both bounds of kernel footprint in range [-N/2,N/2-1] ixMin = int(std::ceil(kx-interp.xrange())) % _N; if (ixMin < -No2) ixMin += _N; if (ixMin >= No2) ixMin -= _N; ixMax = int(std::floor(kx+interp.xrange())) % _N; if (ixMax < -No2) ixMax += _N; if (ixMax >= No2) ixMax -= _N; } if ( interp.isExactAtNodes() && std::abs(ky - std::floor(ky+0.01)) < 10.*std::numeric_limits<double>::epsilon()) { // y coord lies right on integer value, no interpolation in y direction iyMin = int(std::floor(ky+0.01)) % _N; if (iyMin < -No2) iyMin += _N; if (iyMin >= No2) iyMin -= _N; iyMax = iyMin; } else if (interp.xrange() >= No2) { // use all the elements in row: iyMin = -No2; iyMax = No2-1; } else { // Put both bounds of kernel footprint in range [-N/2,N/2-1] iyMin = int(std::ceil(ky-interp.xrange())) % _N; if (iyMin < -No2) iyMin += _N; if (iyMin >= No2) iyMin -= _N; iyMax = int(std::floor(ky+interp.xrange())) % _N; if (iyMax < -No2) iyMax += _N; if (iyMax >= No2) iyMax -= _N; } dbg<<"ix range = "<<ixMin<<"..."<<ixMax<<std::endl; dbg<<"iy range = "<<iyMin<<"..."<<iyMax<<std::endl; std::complex<double> sum = 0.; const InterpolantXY* ixy = dynamic_cast<const InterpolantXY*> (&interp); if (ixy) { // Interpolant is seperable // We have the opportunity to speed up the calculation by // re-using the sums over rows. So we will keep a // cache of them. if (kx != _cacheX || ixy != _cacheInterp) { clearCache(); _cacheX = kx; _cacheInterp = ixy; } else if (iyMax==iyMin && !_cache.empty()) { // Special case for interpolation on a single iy value: // See if we already have this row in cache: int index = iyMin - _cacheStartY; if (index < 0) index += _N; if (index < int(_cache.size())) // We have it! return _cache[index]; else // Desired row not in cache - kill cache, continue as normal. // (But don't clear xwt, since that's still good.) _cache.clear(); } // Build the x component of interpolant int nx = ixMax - ixMin + 1; if (nx<=0) nx+=_N; dbg<<"nx = "<<nx<<std::endl; // This is also cached if possible. It gets cleared when kx != cacheX above. if (_xwt.empty()) { _xwt.resize(nx); int ix = ixMin; for (int i=0; i<nx; ++i, ++ix) { dbg<<"Call xvalWrapped1d for ix-kx = "<<ix<<" - "<<kx<<" = "<<ix-kx<<std::endl; _xwt[i] = ixy->xvalWrapped1d(ix-kx, _N); dbg<<"xwt["<<i<<"] = "<<_xwt[i]<<std::endl; } } else { assert(int(_xwt.size()) == nx); } // cache always holds sequential y values (with wrap). Throw away // elements until we get to the one we need first std::deque<std::complex<double> >::iterator nextSaved = _cache.begin(); while (nextSaved != _cache.end() && _cacheStartY != iyMin) { _cache.pop_front(); _cacheStartY++; if (_cacheStartY >= No2) _cacheStartY-= _N; nextSaved = _cache.begin(); } // Accumulate sum of // interp.xvalWrapped(ix-kx, iy-ky, N)*kval(ix,iy); // Which separates into // ixy->xvalWrapped(ix-kx) * ixy->xvalWrapped(iy-ky) * kval(ix,iy) // The first factor is saved in xwt // The second factor is constant for a given iy, so do that at the end of the loop. // The third factor is the only one that needs to be computed for each ix,iy. int ny = iyMax - iyMin + 1; if (ny<=0) ny+=_N; int iy = iyMin; for (int j = 0; j<ny; j++, iy++) { if (iy >= No2) iy-=_N; // wrap iy if needed dbg<<"j = "<<j<<", iy = "<<iy<<std::endl; std::complex<double> sumy = 0.; if (nextSaved != _cache.end()) { // This row is cached sumy = *nextSaved; ++nextSaved; } else { // Need to compute a new row's sum int ix = ixMin; #if 0 // Simple loop preserved for comparison. for (int i=0; i<nx; i++, ix++) { if (ix > N/2) ix-=N; //check for wrap dbg<<"i = "<<i<<", ix = "<<ix<<std::endl; dbg<<"xwt = "<<_xwt[i]<<", kval = "<<kval(ix,iy)<<std::endl; sumy += _xwt[i]*kval(ix,iy); dbg<<"index = "<<index(ix,iy)<<", sumy -> "<<sumy<<std::endl; } #else // Faster way using ptrs, which doesn't need to do index(ix,iy) every time. int count = nx; std::vector<double>::const_iterator xwt_it = _xwt.begin(); // First do any initial negative ix values: if (ix < 0) { dbg<<"Some initial negative ix: ix = "<<ix<<std::endl; const std::complex<double>* ptr = _array.get() + index(ix,iy); int count1 = std::min(count, -ix); dbg<<"count1 = "<<count1<<std::endl; count -= count1; // Note: ptr goes down in this loop, since ix is negative. for(; count1; --count1) sumy += (*xwt_it++) * conj(*ptr--); ix = 0; } // Next do positive ix values: if (count) { dbg<<"Positive ix: ix = "<<ix<<std::endl; const std::complex<double>* ptr = _array.get() + index(ix,iy); int count1 = std::min(count, No2+1-ix); dbg<<"count1 = "<<count1<<std::endl; count -= count1; for(; count1; --count1) sumy += (*xwt_it++) * (*ptr++); // Finally if we've wrapped around again, do more negative ix values: if (count) { dbg<<"More negative ix: ix = "<<ix<<std::endl; dbg<<"count = "<<count<<std::endl; ix = -No2 + 1; const std::complex<double>* ptr = _array.get() + index(ix,iy); assert(count < No2-1); for(; count; --count) sumy += (*xwt_it++) * conj(*ptr--); } } assert(xwt_it == _xwt.end()); assert(count == 0); #endif // Add to back of cache if (_cache.empty()) _cacheStartY = iy; _cache.push_back(sumy); nextSaved = _cache.end(); } dbg<<"Call xvalWrapped1d for iy-ky = "<<iy<<" - "<<ky<<" = "<<iy-ky<<std::endl; sum += sumy * ixy->xvalWrapped1d(iy-ky, _N); dbg<<"After multiply by column xvalWrapped: sum = "<<sum<<std::endl; } } else { // Interpolant is not seperable, calculate weight at each point int ny = iyMax - iyMin + 1; if (ny<=0) ny+=_N; int nx = ixMax - ixMin + 1; if (nx<=0) nx+=_N; int iy = iyMin; for (int j = 0; j<ny; j++, iy++) { if (iy >= No2) iy-=_N; // wrap iy if needed int ix = ixMin; for (int i=0; i<nx; i++, ix++) { if (ix > No2) ix-=_N; //check for wrap // use kval to keep track of conjugations sum += interp.xvalWrapped(ix-kx, iy-ky, _N)*kval(ix,iy); } } } dbg<<"Done: sum = "<<sum<<std::endl; return sum; }