hashtable<NodeSharedPtr,coordinates> multiforce(MLNetworkSharedPtr mnet, double width, double length, int iterations) { hashtable<NodeSharedPtr,coordinates> pos; hashtable<NodeSharedPtr,coordinates> disp; double t = std::sqrt(width*width+length*length); double area = width*length; double k = std::sqrt(area/mnet->get_actors().size()); for (ActorSharedPtr a: mnet->get_actors()) { double y = drand()*length-length/2; double x = drand()*width-width/2; for (NodeSharedPtr n: mnet->get_nodes(a)) { pos[n].y = x; pos[n].x = y; pos[n].z = mnet->get_layers().get_index(n->layer->id); } } for (int i=0; i<iterations; i++) { // calculate repulsive forces for (LayerSharedPtr l: mnet->get_layers()) { for (NodeSharedPtr v: mnet->get_nodes(l)) { disp[v].x = 0; disp[v].y = 0; for (NodeSharedPtr u: mnet->get_nodes(l)) { if (u == v) continue; coordinates Delta; Delta.x = pos[v].x - pos[u].x; Delta.y = pos[v].y - pos[u].y; double DeltaNorm = std::sqrt(Delta.x*Delta.x+Delta.y*Delta.y); disp[v].x = disp[v].x + Delta.x/DeltaNorm*fr(DeltaNorm,k); disp[v].y = disp[v].y + Delta.y/DeltaNorm*fr(DeltaNorm,k); } } } // calculate attractive forces inside each layer for ((u, v) ∈ E) do for (LayerSharedPtr l: mnet->get_layers()) { for (EdgeSharedPtr e: mnet->get_edges(l,l)) { NodeSharedPtr v = e->v1; NodeSharedPtr u = e->v2; coordinates Delta; Delta.x = pos[v].x - pos[u].x; Delta.y = pos[v].y - pos[u].y; double DeltaNorm = std::sqrt(Delta.x*Delta.x+Delta.y*Delta.y); disp[v].x = disp[v].x - Delta.x/DeltaNorm*fain(DeltaNorm,k); disp[v].y = disp[v].y - Delta.y/DeltaNorm*fain(DeltaNorm,k); disp[u].x = disp[u].x + Delta.x/DeltaNorm*fain(DeltaNorm,k); disp[u].y = disp[u].y + Delta.y/DeltaNorm*fain(DeltaNorm,k); } } // calculate attractive forces across layers for (ActorSharedPtr a: mnet->get_actors()) { for (NodeSharedPtr v: mnet->get_nodes(a)) { for (NodeSharedPtr u: mnet->get_nodes(a)) { if (v == u) continue; coordinates Delta; Delta.x = pos[v].x - pos[u].x; Delta.y = pos[v].y - pos[u].y; double DeltaNorm = std::sqrt(Delta.x*Delta.x+Delta.y*Delta.y); disp[v].x = disp[v].x - Delta.x/DeltaNorm*fainter(DeltaNorm,k); disp[v].y = disp[v].y - Delta.y/DeltaNorm*fainter(DeltaNorm,k); disp[u].x = disp[u].x + Delta.x/DeltaNorm*fainter(DeltaNorm,k); disp[u].y = disp[u].y + Delta.y/DeltaNorm*fainter(DeltaNorm,k); } } } // assign new positions for (NodeSharedPtr v: mnet->get_nodes()) { double dispNorm = std::sqrt(disp[v].x*disp[v].x+disp[v].y*disp[v].y); pos[v].x = pos[v].x + (disp[v].x/dispNorm);//*std::min(dispNorm,t); pos[v].y = pos[v].y + (disp[v].y/dispNorm);//*std::min(dispNorm,t); //pos[v].x = std::min(width/2, std::max(-width/2, pos[v].x)); //pos[v].y = std::min(length/2, std::max(-length/2, pos[v].y)); } // reduce the temperature t -= (t-1)/(iterations+1); } // DEBUG PRINT double min_x = 100000000; double min_y = 100000000; double max_x = -100000000; double max_y = -100000000; for (NodeSharedPtr v: mnet->get_nodes()) { if (pos[v].x < min_x) min_x = pos[v].x; if (pos[v].y < min_y) min_y = pos[v].y; if (pos[v].x > max_x) max_x = pos[v].x; if (pos[v].y > max_y) max_y = pos[v].y; } std::cout << "plot(c(),xlim=c(" << min_x << "," << max_x << "),ylim=c(" << min_y << "," << max_y << "))" << std::endl; //std::cout << "legend(4,4,0:" << (iterations-1) << ",fill=1:" << (iterations) << ")" << std::endl; for (NodeSharedPtr n: mnet->get_nodes()) { std::cout << "points(" << pos[n].x << "," << pos[n].y << ")" << std::endl; } for (EdgeSharedPtr e: mnet->get_edges()) { std::cout << "lines(c(" << pos[e->v1].x << "," << pos[e->v2].x << "),c(" << pos[e->v1].y << "," << pos[e->v2].y << "))" << std::endl; } // return pos; }
int fagzToCompact4(libmaus2::util::ArgInfo const & arginfo) { bool const rc = arginfo.getValue<unsigned int>("rc",1); bool const gz = arginfo.getValue<unsigned int>("gz",1); std::vector<std::string> inputfilenames; inputfilenames = arginfo.restargs; if ( arginfo.hasArg("inputfilenames") ) { std::string const inf = arginfo.getUnparsedValue("inputfilenames",std::string()); libmaus2::aio::InputStream::unique_ptr_type Pinf(libmaus2::aio::InputStreamFactoryContainer::constructUnique(inf)); while ( *Pinf ) { std::string line; std::getline(*Pinf,line); if ( line.size() ) inputfilenames.push_back(line); } } std::string const inlcp = libmaus2::util::OutputFileNameTools::lcp(inputfilenames); std::string defout = inlcp; defout = libmaus2::util::OutputFileNameTools::clipOff(defout,".gz"); defout = libmaus2::util::OutputFileNameTools::clipOff(defout,".fasta"); defout = libmaus2::util::OutputFileNameTools::clipOff(defout,".fa"); std::string const outputfilename = arginfo.getUnparsedValue("outputfilename",defout + ".compact"); std::string const metaoutputfilename = outputfilename + ".meta"; int const verbose = arginfo.getValue<int>("verbose",1); libmaus2::autoarray::AutoArray<char> B(8*1024,false); libmaus2::bitio::CompactArrayWriterFile compactout(outputfilename,2 /* bits per symbol */); if ( ! rc ) std::cerr << "[V] not storing reverse complements" << std::endl; // forward mapping table libmaus2::autoarray::AutoArray<uint8_t> ftable(256,false); // rc mapping for mapped symbols libmaus2::autoarray::AutoArray<uint8_t> ctable(256,false); std::fill(ftable.begin(),ftable.end(),4); std::fill(ctable.begin(),ctable.end(),4); ftable['a'] = ftable['A'] = 0; ftable['c'] = ftable['C'] = 1; ftable['g'] = ftable['G'] = 2; ftable['t'] = ftable['T'] = 3; uint64_t insize = 0; ctable[0] = 3; // A->T ctable[1] = 2; // C->G ctable[2] = 1; // G->C ctable[3] = 0; // T->A libmaus2::aio::OutputStreamInstance::unique_ptr_type metaOut(new libmaus2::aio::OutputStreamInstance(metaoutputfilename)); libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,0); uint64_t nseq = 0; std::vector<uint64_t> lvec; for ( uint64_t i = 0; i < inputfilenames.size(); ++i ) { std::string const fn = inputfilenames[i]; libmaus2::aio::InputStreamInstance CIS(fn); libmaus2::lz::BufferedGzipStream::unique_ptr_type BGS; std::istream * istr = 0; if ( gz ) { libmaus2::lz::BufferedGzipStream::unique_ptr_type tBGS( new libmaus2::lz::BufferedGzipStream(CIS)); BGS = UNIQUE_PTR_MOVE(tBGS); istr = BGS.get(); } else { istr = &CIS; } libmaus2::fastx::StreamFastAReaderWrapper fain(*istr); libmaus2::fastx::StreamFastAReaderWrapper::pattern_type pattern; while ( fain.getNextPatternUnlocked(pattern) ) { if ( verbose ) std::cerr << (i+1) << " " << stripAfterDot(basename(fn)) << " " << pattern.sid << "..."; libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,pattern.spattern.size()); lvec.push_back(pattern.spattern.size()); libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,0); // map symbols for ( uint64_t j = 0; j < pattern.spattern.size(); ++j ) pattern.spattern[j] = ftable[static_cast<uint8_t>(pattern.spattern[j])]; // replace blocks of N symbols by random bases uint64_t l = 0; // number of replaced blocks uint64_t nr = 0; while ( l < pattern.spattern.size() ) { // skip regular bases while ( l < pattern.spattern.size() && pattern.spattern[l] < 4 ) ++l; assert ( l == pattern.spattern.size() || pattern.spattern[l] == 4 ); // go to end of non regular bases block uint64_t h = l; while ( h < pattern.spattern.size() && pattern.spattern[h] == 4 ) ++h; // if non regular block is not empty if ( h-l ) { // replace by random bases for ( uint64_t j = l; j < h; ++j ) pattern.spattern[j] = (libmaus2::random::Random::rand8() & 3); // write bounds libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,l); libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,h); // add to interval counter nr += 1; } l = h; } // make sure there are no more irregular bases for ( uint64_t j = 0; j < pattern.spattern.size(); ++j ) assert ( pattern.spattern[j] < 4 ); // go back to start of meta data metaOut->seekp( - static_cast<int64_t>(2*nr+1)*sizeof(uint64_t), std::ios::cur ); // write number of intervals replaced libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,nr); // skip interval bounds already written metaOut->seekp( static_cast<int64_t>(2*nr )*sizeof(uint64_t), std::ios::cur ); // write bases compactout.write(pattern.spattern.c_str(),pattern.spattern.size()); // write reverse complement if requested if ( rc ) { // reverse complement std::reverse(pattern.spattern.begin(),pattern.spattern.end()); for ( uint64_t j = 0; j < pattern.spattern.size(); ++j ) pattern.spattern[j] = ctable[static_cast<uint8_t>(pattern.spattern[j])]; // write compactout.write(pattern.spattern.c_str(),pattern.spattern.size()); } insize += pattern.spattern.size()+1; nseq += 1; if ( verbose ) std::cerr << "done, input size " << formatBytes(pattern.spattern.size()+1) << " acc " << formatBytes(insize) << std::endl; } } metaOut->seekp(0); libmaus2::util::NumberSerialisation::serialiseNumber(*metaOut,nseq); metaOut->flush(); metaOut.reset(); libmaus2::aio::InputStreamInstance::unique_ptr_type metaISI(new libmaus2::aio::InputStreamInstance(metaoutputfilename)); // number of sequences uint64_t const rnseq = libmaus2::util::NumberSerialisation::deserialiseNumber(*metaISI); assert ( nseq == rnseq ); for ( uint64_t i = 0; i < nseq; ++i ) { // length of sequence uint64_t const l = libmaus2::util::NumberSerialisation::deserialiseNumber(*metaISI); assert ( l == lvec[i] ); uint64_t const nr = libmaus2::util::NumberSerialisation::deserialiseNumber(*metaISI); // skip replaced intervals metaISI->ignore(2*nr*sizeof(uint64_t)); } assert ( metaISI->peek() == std::istream::traits_type::eof() ); std::cerr << "Done, total input size " << insize << std::endl; compactout.flush(); return EXIT_SUCCESS; }