void Aligner::align_internal(Alignment& alignment, vector<Alignment>* multi_alignments, Graph& g, int64_t pinned_node_id, bool pin_left, int32_t max_alt_alns, bool print_score_matrices) { // check input integrity if (pin_left && !pinned_node_id) { cerr << "error:[Aligner] cannot choose pinned end in non-pinned alignment" << endl; exit(EXIT_FAILURE); } if (multi_alignments && !pinned_node_id) { cerr << "error:[Aligner] multiple traceback is not valid in local alignment, only pinned and global" << endl; exit(EXIT_FAILURE); } if (!(multi_alignments) && max_alt_alns != 1) { cerr << "error:[Aligner] cannot specify maximum number of alignments in single alignment" << endl; exit(EXIT_FAILURE); } // alignment pinning algorithm is based on pinning in bottom right corner, if pinning in top // left we need to reverse all the sequences first and translate the alignment back later // create reversed objects if necessary Graph reversed_graph; string reversed_sequence; if (pin_left) { reversed_sequence.resize(alignment.sequence().length()); reverse_copy(alignment.sequence().begin(), alignment.sequence().end(), reversed_sequence.begin()); reverse_graph(g, reversed_graph); } // choose forward or reversed objects Graph* align_graph; string* align_sequence; if (pin_left) { align_graph = &reversed_graph; align_sequence = &reversed_sequence; } else { align_graph = &g; align_sequence = alignment.mutable_sequence(); } // convert into gssw graph and get the counterpart to pinned node (if pinning) gssw_node* pinned_node = nullptr; gssw_graph* graph = create_gssw_graph(*align_graph, pinned_node_id, &pinned_node); if (pinned_node_id & !pinned_node) { cerr << "error:[Aligner] pinned node for pinned alignment is not in graph" << endl; exit(EXIT_FAILURE); } // perform dynamic programming gssw_graph_fill(graph, (*align_sequence).c_str(), nt_table, score_matrix, gap_open, gap_extension, 15, 2); // traceback either from pinned position or optimal local alignment if (pinned_node) { // trace back pinned alignment gssw_graph_mapping** gms = gssw_graph_trace_back_pinned_multi (graph, pinned_node, max_alt_alns, (*align_sequence).c_str(), (*align_sequence).size(), nt_table, score_matrix, gap_open, gap_extension); if (pin_left) { // translate graph and mappings into original node space unreverse_graph(reversed_graph); for (int32_t i = 0; i < max_alt_alns; i++) { unreverse_graph_mapping(gms[i]); } } // convert optimal alignment and store it in the input Alignment object (in the multi alignment, // this will have been set to the first in the vector) if (gms[0]->score > 0) { // have a mapping, can just convert normally gssw_mapping_to_alignment(graph, gms[0], alignment, print_score_matrices); } else { // gssw will not identify mappings with 0 score, infer location based on pinning Mapping* mapping = alignment.mutable_path()->add_mapping(); mapping->set_rank(1); // locate at the end of the node Position* position = mapping->mutable_position(); position->set_node_id(pinned_node_id); position->set_offset(pin_left ? 0 : pinned_node->len); // soft clip Edit* edit = mapping->add_edit(); edit->set_to_length(alignment.sequence().length()); edit->set_sequence(alignment.sequence()); } if (multi_alignments) { // determine how many non-null alignments were returned int32_t num_non_null = max_alt_alns; for (int32_t i = 1; i < max_alt_alns; i++) { if (gms[i]->score <= 0) { num_non_null = i; break; } } // reserve to avoid illegal access errors that occur when the vector reallocates multi_alignments->reserve(num_non_null); // copy the primary alignment multi_alignments->emplace_back(alignment); // convert the alternate alignments and store them at the back of the vector (this will not // execute if we are doing single alignment) for (int32_t i = 1; i < num_non_null; i++) { gssw_graph_mapping* gm = gms[i]; // make new alignment object multi_alignments->emplace_back(); Alignment& next_alignment = multi_alignments->back(); // copy over sequence information from the primary alignment next_alignment.set_sequence(alignment.sequence()); next_alignment.set_quality(alignment.quality()); // get path of the alternate alignment gssw_mapping_to_alignment(graph, gm, next_alignment, print_score_matrices); } } for (int32_t i = 0; i < max_alt_alns; i++) { gssw_graph_mapping_destroy(gms[i]); } free(gms); } else { // trace back local alignment gssw_graph_mapping* gm = gssw_graph_trace_back (graph, (*align_sequence).c_str(), (*align_sequence).size(), nt_table, score_matrix, gap_open, gap_extension); gssw_mapping_to_alignment(graph, gm, alignment, print_score_matrices); gssw_graph_mapping_destroy(gm); } //gssw_graph_print_score_matrices(graph, sequence.c_str(), sequence.size(), stderr); gssw_graph_destroy(graph); }
void Pileups::compute_from_edit(NodePileup& pileup, int64_t& node_offset, int64_t& read_offset, const Node& node, const Alignment& alignment, const Mapping& mapping, const Edit& edit) { string seq = edit.sequence(); bool is_reverse = mapping.is_reverse(); // ***** MATCH ***** if (edit.from_length() == edit.to_length()) { assert (edit.from_length() > 0); make_match(seq, edit.from_length(), is_reverse); assert(seq.length() == edit.from_length()); int64_t delta = is_reverse ? -1 : 1; for (int64_t i = 0; i < edit.from_length(); ++i) { BasePileup* base_pileup = get_create_base_pileup(pileup, node_offset); // reference_base if empty if (base_pileup->num_bases() == 0) { base_pileup->set_ref_base(node.sequence()[node_offset]); } else { assert(base_pileup->ref_base() == node.sequence()[node_offset]); } // add base to bases field (converting to ,. if match) char base = seq[i]; if (!edit.sequence().empty() && base_equal(seq[i], node.sequence()[node_offset], is_reverse)) { base = is_reverse ? ',' : '.'; } *base_pileup->mutable_bases() += base; // add quality if there if (!alignment.quality().empty()) { *base_pileup->mutable_qualities() += alignment.quality()[read_offset]; } // pileup size increases by 1 base_pileup->set_num_bases(base_pileup->num_bases() + 1); // move right along read, and left/right depending on strand on reference node_offset += delta; ++read_offset; } } // ***** INSERT ***** else if (edit.from_length() < edit.to_length()) { make_insert(seq, is_reverse); assert(edit.from_length() == 0); // we define insert (like sam) as insertion between current and next // position (on forward node coordinates). this means an insertion before // offset 0 is invalid! int64_t insert_offset = is_reverse ? node_offset : node_offset - 1; if (insert_offset >= 0) { BasePileup* base_pileup = get_create_base_pileup(pileup, insert_offset); // reference_base if empty if (base_pileup->num_bases() == 0) { base_pileup->set_ref_base(node.sequence()[insert_offset]); } else { assert(base_pileup->ref_base() == node.sequence()[insert_offset]); } // add insertion string to bases field // todo: should we reverse complement this if mapping is reversed ??? base_pileup->mutable_bases()->append(seq); if (!alignment.quality().empty()) { *base_pileup->mutable_qualities() += alignment.quality()[read_offset]; } // pileup size increases by 1 base_pileup->set_num_bases(base_pileup->num_bases() + 1); } else { // todo: need to either forget about these, or extend pileup format. // easy solution: change insert to come before position, and just add // optional pileup at n+1st base of node. would like to figure out // how samtools does it first... /* stringstream ss; ss << "Warning: pileup does not support insertions before 0th base in node." << " Offending edit: " << pb2json(edit) << endl; #pragma omp critical(cerr) cerr << ss.str(); */ } // move right along read (and stay put on reference) read_offset += edit.to_length(); } // ***** DELETE ***** else { assert(edit.to_length() == 0); assert(edit.sequence().empty()); int64_t del_start = !is_reverse ? node_offset : node_offset - edit.from_length() + 1; seq = node.sequence().substr(del_start, edit.from_length()); make_delete(seq, is_reverse); BasePileup* base_pileup = get_create_base_pileup(pileup, node_offset); // reference_base if empty if (base_pileup->num_bases() == 0) { base_pileup->set_ref_base(node.sequence()[node_offset]); } else { assert(base_pileup->ref_base() == node.sequence()[node_offset]); } // add deletion string to bases field // todo: should we reverse complement this if mapping is reversed ??? base_pileup->mutable_bases()->append(seq); if (!alignment.quality().empty()) { *base_pileup->mutable_qualities() += alignment.quality()[read_offset]; } // pileup size increases by 1 base_pileup->set_num_bases(base_pileup->num_bases() + 1); int64_t delta = is_reverse ? -edit.from_length() : edit.from_length(); // stay put on read, move left/right depending on strand on reference node_offset += delta; } }
__global__ void kernelPaintParticles3D(ParBox pb, DataBox<PitchedBox<float3_X, DIM2> > image, DataSpace<DIM2> transpose, int slice, uint32_t globalOffset, uint32_t sliceDim, Mapping mapper) { typedef typename ParBox::FrameType FRAME; typedef typename MappingDesc::SuperCellSize Block; __shared__ FRAME *frame; __shared__ bool isValid; __syncthreads(); /*wait that all shared memory is initialised*/ bool isImageThread = false; const DataSpace<simDim> threadId(threadIdx); const DataSpace<DIM2> localCell(threadId[transpose.x()], threadId[transpose.y()]); const DataSpace<simDim> block = mapper.getSuperCellIndex(DataSpace<simDim > (blockIdx)); const DataSpace<simDim> blockOffset((block - 1) * Block::getDataSpace()); int localId = threadIdx.z * Block::x * Block::y + threadIdx.y * Block::x + threadIdx.x; if (localId == 0) isValid = false; __syncthreads(); //\todo: guard size should not be set to (fixed) 1 here const DataSpace<simDim> realCell(blockOffset + threadId); //delete guard from cell idx #if(SIMDIM==DIM3) uint32_t globalCell = realCell[sliceDim] + globalOffset; if (globalCell == slice) #endif { atomicExch((int*) &isValid, 1); /*WAW Error in cuda-memcheck racecheck*/ isImageThread = true; } __syncthreads(); if (!isValid) return; /*index in image*/ DataSpace<DIM2> imageCell( realCell[transpose.x()], realCell[transpose.y()]); // counter is always DIM2 typedef DataBox < PitchedBox< float_X, DIM2 > > SharedMem; extern __shared__ float_X shBlock[]; __syncthreads(); /*wait that all shared memory is initialised*/ const DataSpace<simDim> blockSize(blockDim); SharedMem counter(PitchedBox<float_X, DIM2 > ((float_X*) shBlock, DataSpace<DIM2 > (), blockSize[transpose.x()] * sizeof (float_X))); if (isImageThread) { counter(localCell) = float_X(0.0); } if (localId == 0) { frame = &(pb.getFirstFrame(block, isValid)); } __syncthreads(); while (isValid) //move over all Frames { PMACC_AUTO(particle,(*frame)[localId]); if (particle[multiMask_] == 1) { int cellIdx = particle[localCellIdx_]; // we only draw the first slice of cells in the super cell (z == 0) const DataSpace<simDim> particleCellId(DataSpaceOperations<simDim>::template map<Block > (cellIdx)); #if(SIMDIM==DIM3) uint32_t globalParticleCell = particleCellId[sliceDim] + globalOffset + blockOffset[sliceDim]; if (globalParticleCell == slice) #endif { const DataSpace<DIM2> reducedCell(particleCellId[transpose.x()], particleCellId[transpose.y()]); atomicAddWrapper(&(counter(reducedCell)), particle[weighting_] / NUM_EL_PER_PARTICLE); } } __syncthreads(); if (localId == 0) { frame = &(pb.getNextFrame(*frame, isValid)); } __syncthreads(); } if (isImageThread) { /** Note: normally, we would multiply by NUM_EL_PER_PARTICLE again. * BUT: since we are interested in a simple value between 0 and 1, * we stay with this number (normalized to the order of macro * particles) and devide by the number of typical macro particles * per cell */ float_X value = counter(localCell) / float_X(particleInit::NUM_PARTICLES_PER_CELL); // * NUM_EL_PER_PARTICLE; if (value > 1.0) value = 1.0; //image(imageCell).x() = value; visPreview::preParticleDensCol::addRGB(image(imageCell), value, visPreview::preParticleDens_opacity); // cut to [0, 1] if (image(imageCell).x() < float_X(0.0)) image(imageCell).x() = float_X(0.0); if (image(imageCell).x() > float_X(1.0)) image(imageCell).x() = float_X(1.0); if (image(imageCell).y() < float_X(0.0)) image(imageCell).y() = float_X(0.0); if (image(imageCell).y() > float_X(1.0)) image(imageCell).y() = float_X(1.0); if (image(imageCell).z() < float_X(0.0)) image(imageCell).z() = float_X(0.0); if (image(imageCell).z() > float_X(1.0)) image(imageCell).z() = float_X(1.0); } }
void Aligner::gssw_mapping_to_alignment(gssw_graph* graph, gssw_graph_mapping* gm, Alignment& alignment, bool print_score_matrices) { alignment.clear_path(); alignment.set_score(gm->score); alignment.set_query_position(0); Path* path = alignment.mutable_path(); //alignment.set_cigar(graph_cigar(gm)); gssw_graph_cigar* gc = &gm->cigar; gssw_node_cigar* nc = gc->elements; int to_pos = 0; int from_pos = gm->position; //cerr << "gm->position " << gm->position << endl; string& to_seq = *alignment.mutable_sequence(); //cerr << "-------------" << endl; if (print_score_matrices) { gssw_graph_print_score_matrices(graph, to_seq.c_str(), to_seq.size(), stderr); //cerr << alignment.DebugString() << endl; } for (int i = 0; i < gc->length; ++i, ++nc) { if (i > 0) from_pos = 0; // reset for each node after the first // check that the current alignment has a non-zero length gssw_cigar* c = nc->cigar; int l = c->length; if (l == 0) continue; gssw_cigar_element* e = c->elements; Node* from_node = (Node*) nc->node->data; string& from_seq = *from_node->mutable_sequence(); Mapping* mapping = path->add_mapping(); mapping->mutable_position()->set_node_id(nc->node->id); mapping->mutable_position()->set_offset(from_pos); mapping->set_rank(path->mapping_size()); //cerr << from_node->id() << ":" << endl; for (int j=0; j < l; ++j, ++e) { Edit* edit; int32_t length = e->length; //cerr << e->length << e->type << endl; switch (e->type) { case 'M': case 'X': case 'N': { // do the sequences match? // emit a stream of "SNPs" and matches int h = from_pos; int last_start = from_pos; int k = to_pos; for ( ; h < from_pos + length; ++h, ++k) { //cerr << h << ":" << k << " " << from_seq[h] << " " << to_seq[k] << endl; if (from_seq[h] != to_seq[k]) { // emit the last "match" region if (h-last_start > 0) { edit = mapping->add_edit(); edit->set_from_length(h-last_start); edit->set_to_length(h-last_start); } // set up the SNP edit = mapping->add_edit(); edit->set_from_length(1); edit->set_to_length(1); edit->set_sequence(to_seq.substr(k,1)); last_start = h+1; } } // handles the match at the end or the case of no SNP if (h-last_start > 0) { edit = mapping->add_edit(); edit->set_from_length(h-last_start); edit->set_to_length(h-last_start); } to_pos += length; from_pos += length; } break; case 'D': edit = mapping->add_edit(); edit->set_from_length(length); edit->set_to_length(0); from_pos += length; break; case 'I': edit = mapping->add_edit(); edit->set_from_length(0); edit->set_to_length(length); edit->set_sequence(to_seq.substr(to_pos, length)); to_pos += length; break; case 'S': // note that soft clips and insertions are semantically equivalent // and can only be differentiated by their position in the read // with soft clips coming at the start or end edit = mapping->add_edit(); edit->set_from_length(0); edit->set_to_length(length); edit->set_sequence(to_seq.substr(to_pos, length)); to_pos += length; break; default: cerr << "error:[Aligner::gssw_mapping_to_alignment] " << "unsupported cigar op type " << e->type << endl; exit(1); break; } } //cerr << "path to_length " << path_to_length(*path) << endl; } // set identity alignment.set_identity(identity(alignment.path())); }
void CallStmt::ExpandFunction(FunctionDef *func, Fragment *fragment) { size_t argCount = func->GetArgCount(); // check number of parameters if (argCount != fParams.size()) { Error(kErr_ParamCount).Raise(&fLocation); return; } /* statement should look like this: * * CallStmt * | * InlineStmt * | * ScopeStmt * | * BlockStmt * / | \ * DeclareStmt... body of function */ BlockStmt *block = new BlockStmt(); SetBody( new InlineStmt(new ScopeStmt(block), func)); Mapping mapping; for(size_t i=0; i<argCount; i++) { const Expr* arg = fParams[i]; int var = func->GetArgVar(i); int val; switch(func->GetArgType(i)) { case FunctionDef::kConstantArg: if (!arg->Evaluate(val)) { Error(kErr_ParamType, "constant").Raise(&arg->GetLoc()); return; } mapping.Add(var, new AtomExpr(kRCX_ConstantType, val, fLocation)); break; case FunctionDef::kIntegerArg: val = gProgram->NextVirtualVar(); mapping.Add(var, new AtomExpr(kRCX_VariableType, val, fLocation)); { DeclareStmt *ds = new DeclareStmt(func->GetArgName(i), val, fLocation, 1, false, true); ds->SetInitialValue(arg->Clone(0)); block->Add(ds); } break; case FunctionDef::kReferenceArg: val = arg->GetLValue(); if (val == kIllegalVar) { Error(kErr_ParamType, "variable").Raise(&arg->GetLoc()); return; } mapping.Add(var, new AtomExpr(kRCX_VariableType, val, fLocation)); break; case FunctionDef::kConstRefArg: mapping.Add(var, arg->Clone(0)); break; case FunctionDef::kSensorArg: if (RCX_VALUE_TYPE(arg->GetStaticEA()) != kRCX_InputValueType) { Error(kErr_ParamType, "sensor").Raise(&arg->GetLoc()); return; } mapping.Add(var, arg->Clone(0)); break; case FunctionDef::kPointerArg: if (!arg->LValueIsPointer()) { Error(kErr_ParamType, "pointer").Raise(&arg->GetLoc()); return; } mapping.Add(var, arg->Clone(0)); break; case FunctionDef::kConstPtrArg: if (!arg->LValueIsPointer()) { Error(kErr_ParamType, "pointer").Raise(&arg->GetLoc()); return; } val = gProgram->NextVirtualVar(); { DeclareStmt *ds = new DeclareStmt(func->GetArgName(i), val, fLocation, 1, true, true); ds->SetInitialValue(arg->Clone(0)); block->Add(ds); } mapping.Add(var, new AtomExpr(kRCX_VariableType, val, fLocation, true)); break; default: Error(kErr_ParamType, "???").Raise(&fParams[i]->GetLoc()); return; } } // add body of inline and then expand block->Add(func->GetBody()->Clone(&mapping)); Expander e(fragment); Apply(GetBody(), e); }
__global__ void kernelPaintFields( EBox fieldE, BBox fieldB, JBox fieldJ, DataBox<PitchedBox<float3_X, DIM2> > image, DataSpace<DIM2> transpose, const int slice, const uint32_t globalOffset, const uint32_t sliceDim, Mapping mapper) { typedef typename MappingDesc::SuperCellSize Block; const DataSpace<simDim> threadId(threadIdx); const DataSpace<simDim> block = mapper.getSuperCellIndex(DataSpace<simDim > (blockIdx)); const DataSpace<simDim> cell(block * Block::getDataSpace() + threadId); const DataSpace<simDim> blockOffset((block - mapper.getGuardingSuperCells()) * Block::getDataSpace()); const DataSpace<simDim> realCell(cell - MappingDesc::SuperCellSize::getDataSpace() * mapper.getGuardingSuperCells()); //delete guard from cell idx const DataSpace<DIM2> imageCell( realCell[transpose.x()], realCell[transpose.y()]); const DataSpace<simDim> realCell2(blockOffset + threadId); //delete guard from cell idx #if (SIMDIM==DIM3) uint32_t globalCell = realCell2[sliceDim] + globalOffset; if (globalCell != slice) return; #endif // set fields of this cell to vars typename BBox::ValueType field_b = fieldB(cell); typename EBox::ValueType field_e = fieldE(cell); typename JBox::ValueType field_j = fieldJ(cell); #if(SIMDIM==DIM3) field_j = float3_X( field_j.x() * CELL_HEIGHT * CELL_DEPTH, field_j.y() * CELL_WIDTH * CELL_DEPTH, field_j.z() * CELL_WIDTH * CELL_HEIGHT ); #elif (SIMDIM==DIM2) field_j = float3_X( field_j.x() * CELL_HEIGHT, field_j.y() * CELL_WIDTH, field_j.z() * CELL_WIDTH * CELL_HEIGHT ); #endif // reset picture to black // color range for each RGB channel: [0.0, 1.0] float3_X pic = float3_X(0., 0., 0.); // typical values of the fields to normalize them to [0,1] // pic.x() = visPreview::preChannel1(field_b / typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().x(), field_e / typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().y(), field_j / typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().z()); pic.y() = visPreview::preChannel2(field_b / typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().x(), field_e / typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().y(), field_j / typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().z()); pic.z() = visPreview::preChannel3(field_b / typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().x(), field_e / typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().y(), field_j / typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().z()); //visPreview::preChannel1Col::addRGB(pic, // visPreview::preChannel1(field_b * typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().x(), // field_e * typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().y(), // field_j * typicalFields<EM_FIELD_SCALE_CHANNEL1>::get().z()), // visPreview::preChannel1_opacity); //visPreview::preChannel2Col::addRGB(pic, // visPreview::preChannel2(field_b * typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().x(), // field_e * typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().y(), // field_j * typicalFields<EM_FIELD_SCALE_CHANNEL2>::get().z()), // visPreview::preChannel2_opacity); //visPreview::preChannel3Col::addRGB(pic, // visPreview::preChannel3(field_b * typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().x(), // field_e * typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().y(), // field_j * typicalFields<EM_FIELD_SCALE_CHANNEL3>::get().z()), // visPreview::preChannel3_opacity); // draw to (perhaps smaller) image cell image(imageCell) = pic; }
/** take in a configuration xml document and a system context and initialize the transport */ int RpcHttpTransport::init( const DOMNode* config, RefCountedPtr<SysContext>& ctx, iRpcServer* masterServer) { int res = -1; ASSERT_D(status() == keRpcNoState); REFCOUNTED_CAST(iSysComponent, StdLogger, ctx->getComponent( StdLogger::getRegistryName()), _logger); RefCountedPtr<ThdPool> pool; REFCOUNTED_CAST(iSysComponent, ThdPool, ctx->getComponent( ThdPool::getRegistryName()), pool); ASSERT_D(pool != NULL); // inititalize socket environment if (( config != NULL ) && ( config->getNodeType() == DOMNode::ELEMENT_NODE )) { const DOMElement* configElem = (const DOMElement*)config; String val; Mapping attrs; // first configure the server attributes DOMNodeList* nodes = DomUtils::getNodeList( configElem, RPC_LISTEN_PORT ); if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) ) { Mapping::const_iterator it = attrs.find( RPC_BACKLOG_ATTR ); if( it != attrs.end() ) { _port = StringUtils::toInt( val ); _backlog = StringUtils::toInt( (*it).second ); } else { CBLOGERR(_logger, NTEXT("RpcHttpClientTransport::init: can't find attributes to server listener, using defaults")); } } // now configure the client attributes attrs.clear(); nodes = DomUtils::getNodeList( configElem, RPC_PROXY_NAME ); if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) ) { Mapping::const_iterator it = attrs.find( RPC_PROXY_PORTATTR ); if( it != attrs.end() ) { _proxy = val; _proxyPort = StringUtils::toInt( (*it).second ); } else { CBLOGERR(_logger, NTEXT("RpcHttpClientTransport::init: can't find attributes to configure Proxy Port")); } } attrs.clear(); nodes = DomUtils::getNodeList( configElem, RPC_CLIENT_RETRIES ); if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) ) { Mapping::const_iterator it = attrs.find( RPC_CLIENT_TOATTR ); if( it != attrs.end() ) { _retries = StringUtils::toInt( val ); _sleepInterval = StringUtils::toInt( (*it).second ); } else { CBLOGERR(_logger, NTEXT("RpcHttpClientTransport::init: can't find attributes to configure client communications parameters")); } } // setup the rpc address for this server String address; address = Net::getHostName(); address += COLON; address += StringUtils::toString( _port ); _transportAddress.setTransport( RPC_HTTP_NAME ); _transportAddress.setAddress( address ); // all is well set the initial state res = 0; _state = keRpcInitted; } if ( res == 0 ) { RefCountedPtr<MyThdFn> wfn(new MyThdFn( *this, &RpcHttpTransport::myWorkerFunction )); pool->add( 1, (RefCountedPtr<iRunnable> &)wfn ); // inititalize MasterServer Pointer ASSERT_D(masterServer != NULL); _masterServer = masterServer; _triggerEvent.reset(); _startedEvent.reset(); } return res; }
bool NVMeshMender::MungeD3DX( const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, const float bSmoothCreaseAngleRadians, const float* pTextureMatrix, const Option _FixTangents, const Option _FixCylindricalTexGen, const Option _WeightNormalsByFaceSize ) { typedef std::map< std::string, unsigned int > Mapping; typedef std::set< Edge > EdgeSet; typedef std::vector< std::set< unsigned int > > IdenticalVertices; IdenticalVertices IdenticalVertices_; Mapping inmap; Mapping outmap; for ( unsigned int a = 0; a < input.size(); ++a ) { inmap[ input[ a ].Name_ ] = a; } for ( unsigned int b = 0; b < output.size(); ++b ) { output[ b ].intVector_.clear(); output[ b ].floatVector_.clear(); outmap[ output[ b ].Name_ ] = b; } for ( unsigned int c = 0; c < output.size(); ++c ) { // for every output that has a match in the input, just copy it over Mapping::iterator in = inmap.find( output[ c ].Name_ ); if ( in != inmap.end() ) { // copy over existing indices, position, or whatever output[ c ] = input[ (*in).second ]; } } Mapping::iterator want = outmap.find( "indices" ); Mapping::iterator have = inmap.find( "indices" ); if ( have == inmap.end() ) { SetLastError( "Missing indices from input" ); return false; } if ( want == outmap.end() ) { SetLastError( "Missing indices from output" ); return false; } // Go through all required outputs & generate as necessary want = outmap.find( "position" ); have = inmap.find( "position" ); if ( have == inmap.end() ) { SetLastError( "Missing position from input" ); return false; } if ( want == outmap.end() ) { SetLastError( "Missing position from output" ); return false; } Mapping::iterator pos = outmap.find( "position" ); VertexAttribute::FloatVector& positions = output[ (*pos).second ].floatVector_; D3DXVECTOR3* pPositions = (D3DXVECTOR3*)( &( positions[ 0 ] ) ); std::set< unsigned int > EmptySet; for ( unsigned int i = 0; i < positions.size(); i += 3 ) { IdenticalVertices_.push_back( EmptySet ); } // initialize all attributes for ( unsigned int att = 0; att < output.size(); ++att ) { if ( output[ att ].Name_ != "indices" ) { if ( output[ att ].floatVector_.size() == 0 ) { output[ att ].floatVector_ = positions; } } } Mapping::iterator ind = outmap.find( "indices" ); VertexAttribute::IntVector& indices = output[ (*ind).second ].intVector_; int* pIndices = (int*)( &( indices[ 0 ] ) ); D3DXVECTOR3* pNormals = 0; D3DXVECTOR3* pBiNormals = 0; D3DXVECTOR3* pTangents = 0; D3DXVECTOR3* pTex0 = 0; bool bNeedNormals = false; bool bNeedTexCoords = false; bool bComputeTangentSpace = false; // see if texture coords are needed if ( outmap.find( "tex0" ) != outmap.end() ) { bNeedTexCoords = true; } // see if tangent or binormal are needed if ( ( outmap.find( "binormal" ) != outmap.end() ) || ( outmap.find( "tangent" ) != outmap.end() ) ) { bComputeTangentSpace = true; } // see if normals are needed if ( outmap.find( "normal" ) != outmap.end() ) { bNeedNormals = true; } // Compute normals. want = outmap.find( "normal" ); have = inmap.find( "normal" ); bool have_normals = ( inmap.find( "normal" ) != inmap.end() ) ? true : false; if ( bNeedNormals || bComputeTangentSpace ) { // see if normals are provided if ( !have_normals ) { // create normals if ( want == outmap.end() ) { VertexAttribute norAtt; norAtt.Name_ = "normal"; output.push_back( norAtt ); outmap[ "normal" ] = output.size() - 1; want = outmap.find( "normal" ); } // just initialize array so it's the correct size output[ (*want).second ].floatVector_ = positions; VertexAttribute::FloatVector& normals = output[ (*want).second ].floatVector_; // zero out normals for ( unsigned n = 0; n < positions.size(); ++n ) { output[ (*want).second ].floatVector_[ n ] = 0.0f; } pNormals = (D3DXVECTOR3*)( &( output[ (*want).second ].floatVector_[0] ) ); // calculate face normals for each face // & add its normal to vertex normal total for ( unsigned int t = 0; t < indices.size(); t += 3 ) { D3DXVECTOR3 edge0, nedge0; D3DXVECTOR3 edge1, nedge1; edge0 = pPositions[ indices[ t + 1 ] ] - pPositions[ indices[ t + 0 ] ]; edge1 = pPositions[ indices[ t + 2 ] ] - pPositions[ indices[ t + 0 ] ]; D3DXVec3Normalize(&nedge0, &edge0); D3DXVec3Normalize(&nedge1, &edge1); D3DXVECTOR3 faceNormal; D3DXVec3Cross( &faceNormal, &nedge0, &nedge1 ); if ( _WeightNormalsByFaceSize == DontWeightNormalsByFaceSize ) { // Renormalize face normal, so it's not weighted by face size D3DXVec3Normalize( &faceNormal, &faceNormal ); } else { // Leave it as-is, to weight by face size naturally by the cross product result } pNormals[ indices[ t + 0 ] ] += faceNormal; pNormals[ indices[ t + 1 ] ] += faceNormal; pNormals[ indices[ t + 2 ] ] += faceNormal; } // Renormalize each vertex normal for ( unsigned int v = 0; v < output[ (*want).second ].floatVector_.size() / 3; ++v ) { D3DXVec3Normalize( &( pNormals[ v ] ), &( pNormals[ v ] ) ); } } } // Compute texture coordinates. if ( bNeedTexCoords || bComputeTangentSpace ) { have = inmap.find( "tex0" ); want = outmap.find("tex0"); bool have_texcoords = (inmap.find( "tex0" ) != inmap.end()) ? true : false; // see if texcoords are provided if ( !have_texcoords ) { // compute texcoords. if ( want == outmap.end() ) { VertexAttribute texCoordAtt; texCoordAtt.Name_ = "tex0"; output.push_back( texCoordAtt ); outmap[ "tex0" ] = output.size() - 1; want = outmap.find( "tex0" ); } // just initialize array so it's the correct size output[ (*want).second ].floatVector_ = positions; pTex0 = (D3DXVECTOR3*)( &(output[ (*want).second ].floatVector_[ 0 ]) ); // Generate cylindrical coordinates // Find min and max positions for object bounding box D3DXVECTOR3 maxPosition( -FLT_MAX, -FLT_MAX, -FLT_MAX ); D3DXVECTOR3 minPosition( FLT_MAX, FLT_MAX, FLT_MAX ); // there are 1/3 as many vectors as floats const unsigned int theCount = static_cast<unsigned int>(positions.size() / 3.0f); for ( unsigned int i = 0; i < theCount; ++i ) { #ifndef __GNUC__ maxPosition.x = max( maxPosition.x, pPositions[ i ].x ); maxPosition.y = max( maxPosition.y, pPositions[ i ].y ); maxPosition.z = max( maxPosition.z, pPositions[ i ].z ); minPosition.x = min( minPosition.x, pPositions[ i ].x ); minPosition.y = min( minPosition.y, pPositions[ i ].y ); minPosition.z = min( minPosition.z, pPositions[ i ].z ); #endif } // Find major, minor and other axis for cylindrical texgen D3DXVECTOR3 delta = maxPosition - minPosition; delta.x = (float)fabs( delta.x ); delta.y = (float)fabs( delta.y ); delta.z = (float)fabs( delta.z ); bool maxx,maxy,maxz; maxx = maxy = maxz = false; bool minz,miny,minx; minx = miny = minz = false; float deltaMajor; if ( ( delta.x >= delta.y ) && ( delta.x >= delta.z ) ) { maxx = true; deltaMajor = delta.x; if ( delta.y > delta.z ) { minz = true; } else { miny = true; } } else if ( ( delta.z >= delta.y ) && ( delta.z >= delta.x ) ) { maxz = true; deltaMajor = delta.z; if ( delta.y > delta.x ) { minx = true; } else { miny = true; } } else if ( ( delta.y >= delta.z ) && ( delta.y >= delta.x ) ) { maxy = true; deltaMajor = delta.y; if ( delta.x > delta.z ) { minz = true; } else { minx = true; } } for ( unsigned int p = 0; p < theCount; ++p ) { // Find position relative to center of bounding box D3DXVECTOR3 texCoords = ( ( maxPosition + minPosition ) / 2.0f ) - pPositions[ p ]; float Major, Minor, Other = 0.0f; if ( maxx ) { Major = texCoords.x; if ( miny ) { Minor = texCoords.y; Other = texCoords.z; } else { Minor = texCoords.z; Other = texCoords.y; } } else if ( maxy ) { Major = texCoords.y; if ( minx ) { Minor = texCoords.x; Other = texCoords.z; } else { Minor = texCoords.z; Other = texCoords.x; } } else if ( maxz ) { Major = texCoords.z; if ( miny ) { Minor = texCoords.y; Other = texCoords.x; } else { Minor = texCoords.x; Other = texCoords.y; } } float longitude = 0.0f; // Prevent zero or near-zero from being passed into atan2 if ( fabs( Other ) < 0.0001f ) { if ( Other >= 0.0f ) { Other = 0.0001f; } else { Other = -0.0001f; } } // perform cylindrical mapping onto object, and remap from -pi,pi to -1,1 longitude = (float)(( atan2( Minor, Other ) ) / 3.141592654); texCoords.x = 0.5f * longitude + 0.5f; texCoords.y = (Major/deltaMajor) + 0.5f; #ifndef __GNUC__ texCoords.x = max( texCoords.x, 0.0f ); texCoords.y = max( texCoords.y, 0.0f ); texCoords.x = min( texCoords.x, 1.0f ); texCoords.y = min( texCoords.y, 1.0f ); #endif pTex0[ p ].x = texCoords.x-0.25f; if ( pTex0[ p ].x < 0.0f ) pTex0[ p ].x += 1.0; pTex0[ p ].y = 1.0f-texCoords.y; pTex0[ p ].z = 1.0f; } } if ( _FixCylindricalTexGen == FixCylindricalTexGen ) { Mapping::iterator texIter = outmap.find( "tex0" ); VertexAttribute::FloatVector& texcoords = ( output[ (*texIter).second ].floatVector_ ); const unsigned int theSize = indices.size(); for ( unsigned int f = 0; f < theSize; f += 3 ) { for ( int v = 0; v < 3; ++v ) { int start = f + v; int end = start + 1; if ( v == 2 ) { end = f; } float dS = texcoords[ indices[ end ] * 3 + 0 ] - texcoords[ indices[ start ] * 3 + 0 ]; float newS = 0.0f; bool bDoS = false; unsigned int theOneToChange = start; if ( fabs( dS ) >= 0.5f ) { bDoS = true; if ( texcoords[ indices[ start ] * 3 + 0 ] < texcoords[ indices[ end ] * 3 + 0 ] ) { newS = texcoords[ indices[ start ]* 3 + 0 ] + 1.0f; } else { theOneToChange = end; newS = texcoords[ indices[ end ] * 3 + 0 ] + 1.0f; } } if ( bDoS == true ) { unsigned int theNewIndex = texcoords.size() / 3; // Duplicate every part of the vertex for ( unsigned int att = 0; att < output.size(); ++att ) { // No new indices are created, just vertex attributes if ( output[ att ].Name_ != "indices" ) { if ( output[ att ].Name_ == "tex0" ) { output[ att ].floatVector_.push_back( newS ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 1 ] ); // x output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 2 ] ); // z } else { // *3 b/c we are looking up 3vectors in an array of floats output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 0 ] ); // x output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 1 ] ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 2 ] ); // z } } } IdenticalVertices_.push_back( EmptySet ); IdenticalVertices_[ indices[ theOneToChange ] ].insert( theNewIndex ); IdenticalVertices_[ theNewIndex ].insert( indices[ theOneToChange ] ); // point to where the new vertices will go indices[ theOneToChange ] = theNewIndex; } } // for v { for ( int v = 0; v < 3; ++v ) { int start = f + v; int end = start + 1; if ( v == 2 ) { end = f; } float dT = texcoords[ indices[ end ] * 3 + 1 ] - texcoords[ indices[ start ] * 3 + 1 ]; float newT = 0.0f; bool bDoT = false; unsigned int theOneToChange = start; if ( fabs( dT ) >= 0.5f ) { bDoT = true; if ( texcoords[ indices[ start ] * 3 + 1 ] < texcoords[ indices[ end ] * 3 + 1 ] ) { newT = texcoords[ indices[ start ] * 3 + 1 ] + 1.0f; } else { theOneToChange = end; newT = texcoords[ indices[ end ] * 3 + 1 ] + 1.0f; } } if ( bDoT == true ) { unsigned int theNewIndex = texcoords.size() / 3; // Duplicate every part of the vertex for ( unsigned int att = 0; att < output.size(); ++att ) { // No new indices are created, just vertex attributes if ( output[ att ].Name_ != "indices" ) { if ( output[ att ].Name_ == "tex0" ) { output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 0 ] ); // x output[ att ].floatVector_.push_back( newT ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 2 ] ); // z } else { // *3 b/c we are looking up 3vectors in an array of floats output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 0 ] ); // x output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 1 ] ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ theOneToChange ] * 3 + 2 ] ); // z } } } IdenticalVertices_.push_back( EmptySet ); IdenticalVertices_[ theNewIndex ].insert( indices[ theOneToChange ] ); IdenticalVertices_[ indices[ theOneToChange ] ].insert( theNewIndex ); // point to where the new vertices will go indices[ theOneToChange ] = theNewIndex; } } } // for v } // for f } // if fix texgen D3DXMATRIX theMatrix( 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,2); D3DXVECTOR3 v(1, 2, 3); D3DXVec3TransformCoord( &v, &v, &theMatrix); if ( pTextureMatrix ) { Mapping::iterator texIter = outmap.find( "tex0" ); VertexAttribute::FloatVector& texcoords = ( output[ (*texIter).second ].floatVector_ ); // now apply matrix for ( unsigned int v = 0; v < texcoords.size(); v += 3 ) { D3DXVECTOR3* pVector = (D3DXVECTOR3*)( &( texcoords[ v ] ) ); D3DXMATRIX theMatrix( pTextureMatrix[ 0 ], pTextureMatrix[ 1 ], pTextureMatrix[ 2 ], pTextureMatrix[ 3 ], pTextureMatrix[ 4 ], pTextureMatrix[ 5 ], pTextureMatrix[ 6 ], pTextureMatrix[ 7 ], pTextureMatrix[ 8 ], pTextureMatrix[ 9 ], pTextureMatrix[ 10], pTextureMatrix[ 11], pTextureMatrix[ 12], pTextureMatrix[ 13], pTextureMatrix[ 14], pTextureMatrix[ 15] ); D3DXVec3TransformCoord( pVector, pVector, (D3DXMATRIX*)(pTextureMatrix)); } } } if ( bComputeTangentSpace ) { Mapping::iterator texIter = outmap.find( "tex0" ); D3DXVECTOR3* tex = (D3DXVECTOR3*)&( output[ (*texIter).second ].floatVector_[ 0 ] ); typedef std::vector< D3DXVECTOR3 > VecVector; // create tangents want = outmap.find( "tangent" ); if ( want == outmap.end() ) { VertexAttribute tanAtt; tanAtt.Name_ = "tangent"; output.push_back( tanAtt ); outmap[ "tangent" ] = output.size() - 1; want = outmap.find( "tangent" ); } // just initialize array so it's the correct size output[ (*want).second ].floatVector_ = positions; // create binormals want = outmap.find( "binormal" ); if ( want == outmap.end() ) { VertexAttribute binAtt; binAtt.Name_ = "binormal"; output.push_back( binAtt ); outmap[ "binormal" ] = output.size() - 1; want = outmap.find( "binormal" ); } // just initialize array so it's the correct size output[ (*want).second ].floatVector_ = positions; // Create a vector of s,t and sxt for each face of the model VecVector sVector; VecVector tVector; VecVector sxtVector; EdgeSet Edges; const unsigned int theSize = indices.size(); // for each face, calculate its S,T & SxT vector, & store its edges for ( unsigned int f = 0; f < theSize; f += 3 ) { D3DXVECTOR3 edge0; D3DXVECTOR3 edge1; D3DXVECTOR3 s; D3DXVECTOR3 t; // grap position & tex coords again in case they were reallocated pPositions = (D3DXVECTOR3*)( &( positions[ 0 ] ) ); tex = (D3DXVECTOR3*)&( output[ (*texIter).second ].floatVector_[ 0 ] ); // create an edge out of x, s and t edge0.x = pPositions[ indices[ f + 1 ] ].x - pPositions[ indices[ f ] ].x; edge0.y = tex[ indices[ f + 1 ] ].x - tex[ indices[ f ] ].x; edge0.z = tex[ indices[ f + 1 ] ].y - tex[ indices[ f ] ].y; // create an edge out of x, s and t edge1.x = pPositions[ indices[ f + 2 ] ].x - pPositions[ indices[ f ] ].x; edge1.y = tex[ indices[ f + 2 ] ].x - tex[ indices[ f ] ].x; edge1.z = tex[ indices[ f + 2 ] ].y - tex[ indices[ f ] ].y; D3DXVECTOR3 sxt; D3DXVec3Cross( &sxt, &edge0, &edge1 ); float a = sxt.x; float b = sxt.y; float c = sxt.z; float ds_dx = 0.0f; if ( fabs( a ) > 0.000001f ) { ds_dx = - b / a; } float dt_dx = 0.0f; if ( fabs( a ) > 0.000001f ) { dt_dx = - c / a; } // create an edge out of y, s and t edge0.x = pPositions[ indices[ f + 1 ] ].y - pPositions[ indices[ f ] ].y; edge0.y = tex[ indices[ f + 1 ] ].x - tex[ indices[ f ] ].x; edge0.z = tex[ indices[ f + 1 ] ].y - tex[ indices[ f ] ].y; // create an edge out of y, s and t edge1.x = pPositions[ indices[ f + 2 ] ].y - pPositions[ indices[ f ] ].y; edge1.y = tex[ indices[ f + 2 ] ].x - tex[ indices[ f ] ].x; edge1.z = tex[ indices[ f + 2 ] ].y - tex[ indices[ f ] ].y; D3DXVec3Cross( &sxt, &edge0, &edge1 ); a = sxt.x; b = sxt.y; c = sxt.z; float ds_dy = 0.0f; if ( fabs( a ) > 0.000001f ) { ds_dy = -b / a; } float dt_dy = 0.0f; if ( fabs( a ) > 0.000001f ) { dt_dy = -c / a; } // create an edge out of z, s and t edge0.x = pPositions[ indices[ f + 1 ] ].z - pPositions[ indices[ f ] ].z; edge0.y = tex[ indices[ f + 1 ] ].x - tex[ indices[ f ] ].x; edge0.z = tex[ indices[ f + 1 ] ].y - tex[ indices[ f ] ].y; // create an edge out of z, s and t edge1.x = pPositions[ indices[ f + 2 ] ].z - pPositions[ indices[ f ] ].z; edge1.y = tex[ indices[ f + 2 ] ].x - tex[ indices[ f ] ].x; edge1.z = tex[ indices[ f + 2 ] ].y - tex[ indices[ f ] ].y; D3DXVec3Cross( &sxt, &edge0, &edge1 ); a = sxt.x; b = sxt.y; c = sxt.z; float ds_dz = 0.0f; if ( fabs( a ) > 0.000001f ) { ds_dz = -b / a; } float dt_dz = 0.0f; if ( fabs( a ) > 0.000001f ) { dt_dz = -c / a; } // generate coordinate frame from the gradients s = D3DXVECTOR3( ds_dx, ds_dy, ds_dz ); t = D3DXVECTOR3( dt_dx, dt_dy, dt_dz ); D3DXVec3Normalize(&s, &s); D3DXVec3Normalize(&t, &t); D3DXVec3Cross( &sxt, &s, &t ); D3DXVec3Normalize( &sxt, &sxt ); // save vectors for this face sVector.push_back( s ); tVector.push_back( t ); sxtVector.push_back( sxt ); if ( _FixTangents == FixTangents ) { // Look for each edge of the triangle in the edge map, in order to find // a neighboring face along the edge for ( int e = 0; e < 3; ++e ) { Edge edge; int start = f + e; int end = start + 1; if ( e == 2 ) { end = f; } #ifndef __GNUC__ // order vertex indices ( low, high ) edge.v0 = min( indices[ start ], indices[ end ] ); edge.v1 = max( indices[ start ], indices[ end ] ); #endif EdgeSet::iterator iter = Edges.find( edge ); // if we are the only triangle with this edge... if ( iter == Edges.end() ) { // ...then add us to the set of edges edge.face = f / 3; Edges.insert( edge ); } else { // otherwise, check our neighbor's s,t & sxt vectors vs our own const float sAgreement = D3DXVec3Dot( &s, &(sVector[ (*iter).face ]) ); const float tAgreement = D3DXVec3Dot( &t, &(tVector[ (*iter).face ]) ); const float sxtAgreement = D3DXVec3Dot( &sxt, &(sxtVector[ (*iter).face ]) ); // Check Radian angle split limit const float epsilon = (float)cos( bSmoothCreaseAngleRadians ); // if the discontinuity in s, t, or sxt is greater than some epsilon, // duplicate the vertex so it won't smooth with its neighbor anymore if ( ( fabs( sAgreement ) < epsilon ) || ( fabs( tAgreement ) < epsilon ) || ( fabs( sxtAgreement ) < epsilon ) ) { // Duplicate two vertices of this edge for this triangle only. // This way the faces won't smooth with each other, thus // preventing the tangent basis from becoming degenerate // divide by 3 b/c vector is of floats and not vectors const unsigned int theNewIndex = positions.size() / 3; // Duplicate every part of the vertex for ( unsigned int att = 0; att < output.size(); ++att ) { // No new indices are created, just vertex attributes if ( output[ att ].Name_ != "indices" ) { // *3 b/c we are looking up 3vectors in an array of floats output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ start ] * 3 + 0 ] ); // x output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ start ] * 3 + 1 ] ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ start ] * 3 + 2 ] ); // z output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ end ] * 3 + 0 ] ); // x output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ end ] * 3 + 1 ] ); // y output[ att ].floatVector_.push_back( output[ att ].floatVector_[ indices[ end ] * 3 + 2 ] ); // z } } IdenticalVertices_.push_back( EmptySet ); IdenticalVertices_.push_back( EmptySet ); // point to where the new vertices will go indices[ start ] = theNewIndex; indices[ end ] = theNewIndex + 1; } // Now that the vertices are duplicated, smoothing won't occur over this edge, // because the two faces will sum their tangent basis vectors into separate indices } } } // if fixtangents } // Allocate std::vector & Zero out average basis for tangent space smoothing VecVector avgS; VecVector avgT; for ( unsigned int p = 0; p < positions.size(); p += 3 ) { avgS.push_back( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) ); // do S avgT.push_back( D3DXVECTOR3( 0.0f, 0.0f, 0.0f ) ); // now t } // go through faces and add up the bases for each vertex const int theFaceCount = indices.size() / 3; for ( unsigned int face = 0; face < (unsigned int)theFaceCount; ++face ) { // sum bases, so we smooth the tangent space across edges avgS[ pIndices[ face * 3 ] ] += sVector[ face ]; avgT[ pIndices[ face * 3 ] ] += tVector[ face ]; avgS[ pIndices[ face * 3 + 1 ] ] += sVector[ face ]; avgT[ pIndices[ face * 3 + 1 ] ] += tVector[ face ]; avgS[ pIndices[ face * 3 + 2 ] ] += sVector[ face ]; avgT[ pIndices[ face * 3 + 2 ] ] += tVector[ face ]; } if ( _FixCylindricalTexGen == FixCylindricalTexGen ) { for ( unsigned int v = 0; v < IdenticalVertices_.size(); ++v ) { // go through each vertex & sum up it's true neighbors for ( std::set< unsigned int >::iterator iter = IdenticalVertices_[ v ].begin(); iter != IdenticalVertices_[ v ].end(); ++iter ) { avgS[ v ] += avgS[ *iter ]; avgT[ v ] += avgT[ *iter ]; } } } Mapping::iterator tangent = outmap.find( "tangent" ); Mapping::iterator binormal = outmap.find( "binormal" ); // now renormalize for ( unsigned int b = 0; b < positions.size(); b += 3 ) { D3DXVECTOR3* vecTangent = (D3DXVECTOR3*)&output[ (*tangent).second ].floatVector_[ b ]; D3DXVECTOR3* vecBinormals = (D3DXVECTOR3*)&output[ (*binormal).second ].floatVector_[ b ]; D3DXVec3Normalize( vecTangent, &avgS[ b / 3 ] ); // s D3DXVec3Normalize( vecBinormals, &avgT[ b / 3 ] ); // T } } // At this point, tex coords, normals, binormals and tangents should be generated if necessary, // and other attributes are simply copied as available return true; }
bool ConfigDialog::store(Mapping& archive) { archive.write("showViewMarker", viewMarkerCheck.isChecked()); archive.write("directory", directoryEntry.string()); archive.write("basename", basenameEntry.string()); archive.write("checkStartTime", startTimeCheck.isChecked()); archive.write("startTime", startTimeSpin.value()); archive.write("checkFinishTime", finishTimeCheck.isChecked()); archive.write("finishTime", finishTimeSpin.value()); archive.write("fps", fpsSpin.value()); archive.write("setSize", imageSizeCheck.isChecked()); archive.write("width", imageWidthSpin.value()); archive.write("height", imageHeightSpin.value()); archive.write("mouseCursor", mouseCursorCheck.isChecked()); return true; }
void ConfigDialog::restore(const Mapping& archive) { viewMarkerCheck.setChecked(archive.get("showViewMarker", viewMarkerCheck.isChecked())); directoryEntry.setText(archive.get("directory", directoryEntry.string())); basenameEntry.setText(archive.get("basename", basenameEntry.string())); startTimeCheck.setChecked(archive.get("checkStartTime", startTimeCheck.isChecked())); startTimeSpin.setValue(archive.get("startTime", startTimeSpin.value())); finishTimeCheck.setChecked(archive.get("checkFinishTime", finishTimeCheck.isChecked())); finishTimeSpin.setValue(archive.get("finishTime", finishTimeSpin.value())); fpsSpin.setValue(archive.get("fps", fpsSpin.value())); imageSizeCheck.setChecked(archive.get("setSize", imageSizeCheck.isChecked())); imageWidthSpin.setValue(archive.get("width", imageWidthSpin.value())); imageHeightSpin.setValue(archive.get("height", imageHeightSpin.value())); mouseCursorCheck.setChecked(archive.get("mouseCursor", mouseCursorCheck.isChecked())); }
bool Task::restoreState(AbstractTaskSequencer* sequencer, const Mapping& archive) { sequencer->setCurrentPhase(archive.get("phaseIndex", 0)); return true; }
bool Task::storeState(AbstractTaskSequencer* sequencer, Mapping& archive) { archive.write("phaseIndex", sequencer->currentPhaseIndex()); return true; }
Alignment Filter::depth_filter(Alignment& aln){ if (use_avg && window_length != 0){ } else if (use_avg != 0){ } else{ } Path path = aln.path(); //TODO handle reversing mappings vector<int>* qual_window; if (window_length > 0){ qual_window = new vector<int>(); } for (int i = 0; i < path.mapping_size(); i++){ Mapping mapping = path.mapping(i); Position start_pos = mapping.position(); int64_t start_node = start_pos.node_id(); int64_t start_offset = start_pos.offset(); int64_t curr_offset_in_graph = 0; int64_t curr_offset_in_alignment = 0; stringstream pst; pst << start_node << "_" << curr_offset_in_graph; string p_hash = pst.str(); for (int j = 0; j < mapping.edit_size(); j++){ Edit ee = mapping.edit(j); if (ee.from_length() == ee.to_length() && ee.sequence() == ""){ if (!filter_matches){ continue; } } stringstream est; est << ee.from_length() << "_" << ee.to_length() << "_" + ee.sequence(); string e_hash = est.str(); #pragma omp critical(write) pos_to_edit_to_depth[p_hash][e_hash] += 1; /** * If an edit fails the filter, either return a new empty alignment * OR * return a new alignment identical to the old one EXCEPT where * the offending edit has been replaced by a match to the reference. */ if (pos_to_edit_to_depth[p_hash][e_hash] < min_depth){ if (!remove_failing_edits){ return inverse ? aln : Alignment(); } else { Alignment edited_aln = Alignment(aln); edited_aln.mutable_path()->mutable_mapping(i)->mutable_edit(j)->set_sequence(""); edited_aln.mutable_path()->mutable_mapping(i)->mutable_edit(j)->set_from_length(ee.from_length()); edited_aln.mutable_path()->mutable_mapping(i)->mutable_edit(j)->set_to_length(ee.from_length()); return edited_aln; } } } return inverse ? Alignment() : aln; } }
// merge that properly handles long indels // assumes that alignments should line up end-to-end Alignment merge_alignments(const vector<Alignment>& alns, bool debug) { if (alns.size() == 0) { Alignment aln; return aln; } else if (alns.size() == 1) { return alns.front(); } // where possible get node and target lengths // to validate after merge /* map<int64_t, map<size_t, set<const Alignment*> > > node_lengths; map<int64_t, map<size_t, set<const Alignment*> > > to_lengths; for (auto& aln : alns) { auto& path = aln.path(); // find a mapping that overlaps the whole node // note that edits aren't simplified // so deletions are intact for (size_t i = 0; i < path.mapping_size(); ++i) { auto& m = path.mapping(i); if (m.position().offset() == 0) { // can we see if the next mapping is on the following node if (i < path.mapping_size()-1 && path.mapping(i+1).position().offset() == 0 && mapping_from_length(path.mapping(i+1)) && mapping_from_length(m)) { // we cover the node, record the to_length and from_length set<const Alignment*>& n = node_lengths[m.position().node_id()][from_length(m)]; n.insert(&aln); set<const Alignment*>& t = to_lengths[m.position().node_id()][to_length(m)]; t.insert(&aln); } } } } // verify our input by checking for disagreements for (auto& n : node_lengths) { auto& node_id = n.first; if (n.second.size() > 1) { cerr << "disagreement in node lengths for " << node_id << endl; for (auto& l : n.second) { cerr << "alignments that report length of " << l.first << endl; for (auto& a : l.second) { cerr << pb2json(*a) << endl; } } } else { //cerr << n.second.begin()->second.size() << " alignments support " // << n.second.begin()->first << " as length for " << node_id << endl; } } */ // parallel merge algorithm // for each generation // merge 0<-0+1, 1<-2+3, ... // until there is only one alignment vector<Alignment> last = alns; // get the alignments ready for merge #pragma omp parallel for for (size_t i = 0; i < last.size(); ++i) { Alignment& aln = last[i]; //cerr << "on " << i << "th aln" << endl // << pb2json(aln) << endl; if (!aln.has_path()) { Mapping m; Edit* e = m.add_edit(); e->set_to_length(aln.sequence().size()); e->set_sequence(aln.sequence()); *aln.mutable_path()->add_mapping() = m; } } while (last.size() > 1) { //cerr << "last size " << last.size() << endl; size_t new_count = last.size()/2; //cerr << "new count b4 " << new_count << endl; new_count += last.size() % 2; // force binary //cerr << "New count = " << new_count << endl; vector<Alignment> curr; curr.resize(new_count); #pragma omp parallel for for (size_t i = 0; i < curr.size(); ++i) { //cerr << "merging " << 2*i << " and " << 2*i+1 << endl; // take a pair from the old alignments // merge them into this one if (2*i+1 < last.size()) { auto& a1 = last[2*i]; auto& a2 = last[2*i+1]; curr[i] = merge_alignments(a1, a2, debug); // check that the merge did the right thing /* auto& a3 = curr[i]; for (size_t j = 0; j < a3.path().mapping_size()-1; ++j) { // look up reported node length // and compare to what we saw // skips last mapping auto& m = a3.path().mapping(j); if (from_length(m) == to_length(m) && m.has_position() && m.position().offset()==0 && a3.path().mapping(j+1).has_position() && a3.path().mapping(j+1).position().offset()==0) { auto nl = node_lengths.find(m.position().node_id()); if (nl != node_lengths.end()) { if (nl->second.find(from_length(m)) == nl->second.end()) { cerr << "node length is not consistent for " << m.position().node_id() << endl; cerr << "expected " << nl->second.begin()->first << endl; cerr << "got " << from_length(m) << endl; cerr << "inputs:" << endl << pb2json(a1) << endl << pb2json(a2) << endl << "output: " << endl << pb2json(a3) << endl; //exit(1); } } } } */ } else { auto& a1 = last[2*i]; //cerr << "no need to merge" << endl; curr[i] = a1; } } last = curr; } Alignment res = last.front(); *res.mutable_path() = simplify(res.path()); return res; }
DINLINE void operator()(ParBoxIons ionBox, ParBoxElectrons electronBox, FrameIonizer frameIonizer, Mapping mapper) const { /* "particle box" : container/iterator where the particles live in * and where one can get the frame in a super cell from */ typedef typename ParBoxElectrons::FrameType ELECTRONFRAME; typedef typename ParBoxIons::FrameType IONFRAME; typedef typename ParBoxIons::FramePtr IonFramePtr; typedef typename ParBoxElectrons::FramePtr ElectronFramePtr; /* specify field to particle interpolation scheme */ typedef typename PMacc::traits::Resolve< typename GetFlagType<IONFRAME,interpolation<> >::type >::type InterpolationScheme; /* margins around the supercell for the interpolation of the field on the cells */ typedef typename GetMargin<InterpolationScheme>::LowerMargin LowerMargin; typedef typename GetMargin<InterpolationScheme>::UpperMargin UpperMargin; /* relevant area of a block */ typedef SuperCellDescription< typename MappingDesc::SuperCellSize, LowerMargin, UpperMargin > BlockDescription_; /* for not mixing operations::assign up with the nvidia functor assign */ namespace partOp = PMacc::particles::operations; /* definitions for domain variables, like indices of blocks and threads */ typedef typename BlockDescription_::SuperCellSize SuperCellSize; /* multi-dimensional offset vector from local domain origin on GPU in units of super cells */ const DataSpace<simDim> block(mapper.getSuperCellIndex(DataSpace<simDim > (blockIdx))); /* multi-dim vector from origin of the block to a cell in units of cells */ const DataSpace<simDim > threadIndex(threadIdx); /* conversion from a multi-dim cell coordinate to a linear coordinate of the cell in its super cell */ const int linearThreadIdx = DataSpaceOperations<simDim>::template map<SuperCellSize > (threadIndex); /* multi-dim offset from the origin of the local domain on GPU * to the origin of the block of the in unit of cells */ const DataSpace<simDim> blockCell = block * SuperCellSize::toRT(); /* subtract guarding cells to only have the simulation volume */ const DataSpace<simDim> localCellIndex = (block * SuperCellSize::toRT() + threadIndex) - mapper.getGuardingSuperCells() * SuperCellSize::toRT(); /* typedef for the functor that writes new macro electrons into electron frames during runtime */ typedef typename particles::ionization::WriteElectronIntoFrame WriteElectronIntoFrame; PMACC_SMEM( ionFrame, IonFramePtr ); PMACC_SMEM( electronFrame,ElectronFramePtr ); PMACC_SMEM( maxParticlesInFrame, lcellId_t ); /* find last frame in super cell * define maxParticlesInFrame as the maximum frame size */ if (linearThreadIdx == 0) { ionFrame = ionBox.getLastFrame(block); maxParticlesInFrame = PMacc::math::CT::volume<SuperCellSize>::type::value; } __syncthreads(); if (!ionFrame.isValid()) return; //end kernel if we have no frames /* caching of E- and B- fields and initialization of random generator if needed */ frameIonizer.init(blockCell, linearThreadIdx, localCellIndex); /* Declare counter in shared memory that will later tell the current fill level or * occupation of the newly created target electron frames. */ PMACC_SMEM( newFrameFillLvl, int ); /* Declare local variable oldFrameFillLvl for each thread */ int oldFrameFillLvl; /* Initialize local (register) counter for each thread * - describes how many new macro electrons should be created */ unsigned int newMacroElectrons = 0; /* Declare local electron ID * - describes at which position in the new frame the new electron is to be created */ int electronId; /* Master initializes the frame fill level with 0 */ if (linearThreadIdx == 0) { newFrameFillLvl = 0; electronFrame = nullptr; } __syncthreads(); /* move over source species frames and call frameIonizer * frames are worked on in backwards order to avoid asking if there is another frame * --> performance * Because all frames are completely filled except the last and apart from that last frame * one wants to make sure that all threads are working and every frame is worked on. */ while (ionFrame.isValid()) { /* casting uint8_t multiMask to boolean */ const bool isParticle = ionFrame[linearThreadIdx][multiMask_]; __syncthreads(); /* < IONIZATION and change of charge states > * if the threads contain particles, the frameIonizer can ionize them * if they are non-particles their inner ionization counter remains at 0 */ if (isParticle) /* ionization based on ionization model - this actually increases charge states*/ frameIonizer(*ionFrame, linearThreadIdx, newMacroElectrons); __syncthreads(); /* always true while-loop over all particles inside source frame until each thread breaks out individually * * **Attention**: Speaking of 1st and 2nd frame only may seem odd. * The question might arise what happens if more electrons are created than would fit into two frames. * Well, multi-ionization during a time step is accounted for. The number of new electrons is * determined inside the outer loop over the valid frames while in the inner loop each thread can create only ONE * new macro electron. But the loop repeats until each thread has created all the electrons needed in the time step. */ while (true) { /* < INIT > * - electronId is initialized as -1 (meaning: invalid) * - (local) oldFrameFillLvl set equal to (shared) newFrameFillLvl for each thread * --> each thread remembers the old "counter" * - then sync */ electronId = -1; oldFrameFillLvl = newFrameFillLvl; __syncthreads(); /* < CHECK & ADD > * - if a thread wants to create electrons in each cycle it can do that only once * and before that it atomically adds to the shared counter and uses the current * value as electronId in the new frame * - then sync */ if (newMacroElectrons > 0) electronId = nvidia::atomicAllInc(&newFrameFillLvl); __syncthreads(); /* < EXIT? > * - if the counter hasn't changed all threads break out of the loop */ if (oldFrameFillLvl == newFrameFillLvl) break; __syncthreads(); /* < FIRST NEW FRAME > * - if there is no frame, yet, the master will create a new target electron frame * and attach it to the back of the frame list * - sync all threads again for them to know which frame to use */ if (linearThreadIdx == 0) { if (!electronFrame.isValid()) { electronFrame = electronBox.getEmptyFrame(); electronBox.setAsLastFrame(electronFrame, block); } } __syncthreads(); /* < CREATE 1 > * - all electrons fitting into the current frame are created there * - internal ionization counter is decremented by 1 * - sync */ if ((0 <= electronId) && (electronId < maxParticlesInFrame)) { /* each thread makes the attributes of its ion accessible */ auto parentIon = (ionFrame[linearThreadIdx]); /* each thread initializes an electron if one should be created */ auto targetElectronFull = (electronFrame[electronId]); /* create an electron in the new electron frame: * - see particles/ionization/ionizationMethods.hpp */ WriteElectronIntoFrame writeElectron; writeElectron(parentIon,targetElectronFull); newMacroElectrons -= 1; } __syncthreads(); /* < SECOND NEW FRAME > * - if the shared counter is larger than the frame size a new electron frame is reserved * and attached to the back of the frame list * - then the shared counter is set back by one frame size * - sync so that every thread knows about the new frame */ if (linearThreadIdx == 0) { if (newFrameFillLvl >= maxParticlesInFrame) { electronFrame = electronBox.getEmptyFrame(); electronBox.setAsLastFrame(electronFrame, block); newFrameFillLvl -= maxParticlesInFrame; } } __syncthreads(); /* < CREATE 2 > * - if the EID is larger than the frame size * - the EID is set back by one frame size * - the thread writes an electron to the new frame * - the internal counter is decremented by 1 */ if (electronId >= maxParticlesInFrame) { electronId -= maxParticlesInFrame; /* each thread makes the attributes of its ion accessible */ auto parentIon = ((*ionFrame)[linearThreadIdx]); /* each thread initializes an electron if one should be produced */ auto targetElectronFull = (electronFrame[electronId]); /* create an electron in the new electron frame: * - see particles/ionization/ionizationMethods.hpp */ WriteElectronIntoFrame writeElectron; writeElectron(parentIon,targetElectronFull); newMacroElectrons -= 1; } __syncthreads(); } __syncthreads(); if (linearThreadIdx == 0) { ionFrame = ionBox.getPreviousFrame(ionFrame); maxParticlesInFrame = PMacc::math::CT::volume<SuperCellSize>::type::value; } __syncthreads(); } } // void kernelIonizeParticles
int main_xg(int argc, char** argv) { if (argc == 2) { help_xg(argv); return 1; } string vg_in; string vg_out; string out_name; string in_name; int64_t node_id; bool edges_from = false; bool edges_to = false; bool edges_of = false; bool edges_on_start = false; bool edges_on_end = false; bool node_sequence = false; string pos_for_char; string pos_for_substr; int context_steps = 0; bool node_context = false; string target; bool print_graph = false; bool text_output = false; bool validate_graph = false; bool extract_threads = false; bool store_threads = false; bool is_sorted_dag = false; string report_name; string b_array_name; int c; optind = 2; // force optind past "xg" positional argument while (true) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"vg", required_argument, 0, 'v'}, {"out", required_argument, 0, 'o'}, {"in", required_argument, 0, 'i'}, {"extract-vg", required_argument, 0, 'X'}, {"node", required_argument, 0, 'n'}, {"char", required_argument, 0, 'P'}, {"substr", required_argument, 0, 'F'}, //{"range", required_argument, 0, 'r'}, {"context", required_argument, 0, 'c'}, {"edges-from", required_argument, 0, 'f'}, {"edges-to", required_argument, 0, 't'}, {"edges-of", required_argument, 0, 'O'}, {"edges-on-start", required_argument, 0, 'S'}, {"edges-on-end", required_argument, 0, 'E'}, {"node-seq", required_argument, 0, 's'}, {"path", required_argument, 0, 'p'}, {"extract-threads", no_argument, 0, 'x'}, {"store-threads", no_argument, 0, 'r'}, {"is-sorted-dag", no_argument, 0, 'd'}, {"report", required_argument, 0, 'R'}, {"debug", no_argument, 0, 'D'}, {"text-output", no_argument, 0, 'T'}, {"validate", no_argument, 0, 'V'}, {"dump-bs", required_argument, 0, 'b'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long (argc, argv, "hv:o:i:X:f:t:s:c:n:p:DxrdTO:S:E:VR:P:F:b:", long_options, &option_index); // Detect the end of the options. if (c == -1) break; switch (c) { case 'v': vg_in = optarg; break; case 'V': validate_graph = true; break; case 'o': out_name = optarg; break; case 'D': print_graph = true; break; case 'T': text_output = true; break; case 'x': extract_threads = true; break; case 'r': store_threads = true; break; case 'd': is_sorted_dag = true; break; case 'i': in_name = optarg; break; case 'X': vg_out = optarg; break; case 'n': node_id = parse<int64_t>(optarg); node_context = true; break; case 'c': context_steps = parse<int>(optarg); break; case 'f': node_id = parse<int64_t>(optarg); edges_from = true; break; case 't': node_id = parse<int64_t>(optarg); edges_to = true; break; case 'O': node_id = parse<int64_t>(optarg); edges_of = true; break; case 'S': node_id = parse<int64_t>(optarg); edges_on_start = true; break; case 'E': node_id = parse<int64_t>(optarg); edges_on_end = true; break; case 's': node_id = parse<int64_t>(optarg); node_sequence = true; break; case 'p': target = optarg; break; case 'P': pos_for_char = optarg; break; case 'F': pos_for_substr = optarg; break; case 'R': report_name = optarg; break; case 'b': b_array_name = optarg; break; case 'h': case '?': help_xg(argv); exit(1); break; default: abort (); } } unique_ptr<XG> graph; //string file_name = argv[optind]; if (in_name.empty()) assert(!vg_in.empty()); if (vg_in == "-") { // Read VG from stdin graph = unique_ptr<XG>(new XG()); graph->from_stream(std::cin, validate_graph, print_graph, store_threads, is_sorted_dag); } else if (vg_in.size()) { // Read VG from a file ifstream in; in.open(vg_in.c_str()); graph = unique_ptr<XG>(new XG()); graph->from_stream(in, validate_graph, print_graph, store_threads, is_sorted_dag); } if (in_name.size()) { get_input_file(in_name, [&](istream& in) { // Load from an XG file or - (stdin) graph = stream::VPKG::load_one<XG>(in); }); } // Prepare structure tree for serialization unique_ptr<sdsl::structure_tree_node> structure; if (!report_name.empty()) { // We need to make a report, so we need the structure. Make a real tree // node. The unique_ptr handles deleting. structure = unique_ptr<sdsl::structure_tree_node>(new sdsl::structure_tree_node("name", "type")); } if(!vg_out.empty()) { if (graph.get() == nullptr) { cerr << "error [vg xg] no xg graph exists to convert; Try: vg xg -i graph.xg -X graph.vg" << endl; return 1; } VG converted; // Convert the xg graph to vg format convert_handle_graph(graph.get(), &converted); // TODO: The converter doesn't copy circular paths yet. // When it does, we can remove all this path copying code. // Make a raw Proto Graph to hold Path objects Graph path_graph; // Since paths are not copied, copy the paths. for (size_t rank = 1; rank <= graph->max_path_rank(); rank++) { // Extract each path into the path graph *path_graph.add_path() = graph->path(graph->path_name(rank)); } // Merge in all the paths converted.extend(path_graph); if (vg_out == "-") { converted.serialize_to_ostream(std::cout); } else { converted.serialize_to_file(vg_out); } } if (!out_name.empty()) { // Open a destination file if it is a file we want to write to ofstream out_file; if (out_name != "-") { out_file.open(out_name); } // Work out where to save to ostream& out = (out_name == "-") ? std::cout : out_file; // Encapsulate output in VPKG stream::VPKG::with_save_stream(out, "XG", [&](ostream& tagged) { // Serialize to the file while recording space usage to the structure. graph->serialize(tagged, structure.get(), "xg"); }); out.flush(); } if (!report_name.empty()) { // Save the report ofstream out; out.open(report_name.c_str()); sdsl::write_structure_tree<HTML_FORMAT>(structure.get(), out, 0); } // queries if (node_sequence) { cout << node_id << ": " << graph->node_sequence(node_id) << endl; } if (!pos_for_char.empty()) { // extract the position from the string int64_t id; bool is_rev; size_t off; extract_pos(pos_for_char, id, is_rev, off); // then pick it up from the graph cout << graph->pos_char(id, is_rev, off) << endl; } if (!pos_for_substr.empty()) { int64_t id; bool is_rev; size_t off; size_t len; extract_pos_substr(pos_for_substr, id, is_rev, off, len); cout << graph->pos_substr(id, is_rev, off, len) << endl; } if (edges_from) { vector<Edge> edges = graph->edges_from(node_id); for (auto& edge : edges) { cout << edge.from() << (edge.from_start()?"-":"+") << " -> " << edge.to() << (edge.to_end()?"-":"+") << endl; } } if (edges_to) { vector<Edge> edges = graph->edges_to(node_id); for (auto& edge : edges) { cout << edge.from() << (edge.from_start()?"-":"+") << " -> " << edge.to() << (edge.to_end()?"-":"+") << endl; } } if (edges_of) { vector<Edge> edges = graph->edges_of(node_id); for (auto& edge : edges) { cout << edge.from() << (edge.from_start()?"-":"+") << " -> " << edge.to() << (edge.to_end()?"-":"+") << endl; } } if (edges_on_start) { vector<Edge> edges = graph->edges_on_start(node_id); for (auto& edge : edges) { cout << edge.from() << (edge.from_start()?"-":"+") << " -> " << edge.to() << (edge.to_end()?"-":"+") << endl; } } if (edges_on_end) { vector<Edge> edges = graph->edges_on_end(node_id); for (auto& edge : edges) { cout << edge.from() << (edge.from_start()?"-":"+") << " -> " << edge.to() << (edge.to_end()?"-":"+") << endl; } } if (node_context) { Graph g; graph->neighborhood(node_id, context_steps, g); if (text_output) { to_text(cout, g); } else { vector<Graph> gb = { g }; stream::write_buffered(cout, gb, 0); } } if (!target.empty()) { string name; int64_t start, end; Graph g; parse_region(target, name, start, end); graph->get_path_range(name, start, end, g); graph->expand_context(g, context_steps); if (text_output) { to_text(cout, g); } else { vector<Graph> gb = { g }; stream::write_buffered(cout, gb, 0); } } if (extract_threads) { list<XG::thread_t> threads; for (auto& p : graph->extract_threads(false)) { for (auto& t : p.second) { threads.push_back(t); } } for (auto& p : graph->extract_threads(true)) { for (auto& t : p.second) { threads.push_back(t); } } size_t thread_number = 0; for(XG::thread_t& thread : threads) { // Convert to a Path Path path; for(XG::ThreadMapping& m : thread) { // Convert all the mappings Mapping mapping; mapping.mutable_position()->set_node_id(m.node_id); mapping.mutable_position()->set_is_reverse(m.is_reverse); *(path.add_mapping()) = mapping; } // Give each thread a name path.set_name("_thread_" + to_string(thread_number++)); // We need a Graph for serialization purposes. We do one chunk per // thread in case the threads are long. Graph g; *(g.add_path()) = path; // Dump the graph with its mappings. TODO: can we restrict these to // mappings to nodes we have already pulled out? Or pull out the // whole compressed graph? if (text_output) { to_text(cout, g); } else { vector<Graph> gb = { g }; stream::write_buffered(cout, gb, 0); } } } if (!b_array_name.empty()) { // Dump B array ofstream out; out.open(b_array_name.c_str()); graph->bs_dump(out); } return 0; }
bool PoseSeqItem::convertSub(BodyPtr orgBody, const Mapping& convInfo) { bool converted = false; const Listing& jointMap = *convInfo.findListing("jointMap"); const Mapping& linkMap = *convInfo.findMapping("linkMap"); BodyPtr body = ownerBodyItem->body(); for(PoseSeq::iterator p = seq->begin(); p != seq->end(); ++p){ PosePtr pose = p->get<Pose>(); if(pose){ bool modified = false; seq->beginPoseModification(p); PosePtr orgPose = dynamic_cast<Pose*>(pose->duplicate()); if(jointMap.isValid()){ modified = true; pose->setNumJoints(0); int n = orgPose->numJoints(); for(int i=0; i < n; ++i){ if(orgPose->isJointValid(i)){ if(i < jointMap.size()){ int newJointId = jointMap[i].toInt(); if(newJointId >= 0){ pose->setJointPosition(newJointId, orgPose->jointPosition(i)); pose->setJointStationaryPoint(newJointId, orgPose->isJointStationaryPoint(i)); } } } } } if(linkMap.isValid()){ modified = true; pose->clearIkLinks(); int baseLinkIndex = -1; for(Pose::LinkInfoMap::const_iterator q = orgPose->ikLinkBegin(); q != orgPose->ikLinkEnd(); ++q){ Link* orgLink = orgBody->link(q->first); string linkName; ValueNode* linkNameNode = linkMap.find(orgLink->name()); if(linkNameNode->isValid()){ linkName = linkNameNode->toString(); } else { linkName = orgLink->name(); } Link* link = body->link(linkName); if(link){ const Pose::LinkInfo& orgLinkInfo = q->second; Pose::LinkInfo* linkInfo = pose->addIkLink(link->index()); linkInfo->p = orgLinkInfo.p; linkInfo->R = orgLinkInfo.R; linkInfo->setStationaryPoint(orgLinkInfo.isStationaryPoint()); if(orgLinkInfo.isTouching()){ linkInfo->setTouching(orgLinkInfo.partingDirection()); } linkInfo->setSlave(orgLinkInfo.isSlave()); if(orgLinkInfo.isBaseLink()){ baseLinkIndex = link->index(); } } } if(baseLinkIndex >= 0){ pose->setBaseLink(baseLinkIndex); } } if(modified){ seq->endPoseModification(p); converted = true; } } } return converted; }
int SysPathMgr::init( const DOMNode* config, RefCountedPtr<SysContext>& ctx ) { int res = -1; REFCOUNTED_CAST(iSysComponent, StdLogger, ctx->getComponent( StdLogger::getRegistryName()), _logger); // I expect the config node to be an element node if ( ( config != NULL ) && ( config->getNodeType() == DOMNode::ELEMENT_NODE ) ) { // set the root to be the current directory by default String root(NTEXT(".")); Mapping rootAttrs; if ( DomUtils::getNodeValue( (const DOMElement*)config, NULL, &rootAttrs ) ) { rootAttrs.getIfAvailable(SYS_PATH_ROOTATTR, root); } // resolve whatever we have in the root and then verify a file does not exist // in place of the intended directory _root = FileUtils::resolve( root ); FileAttributes fattrs; if ( !FileUtils::getAttributes( _root, fattrs ) ) { if (!FileUtils::mkdirs( _root )) { CBLOGERR(_logger, NTEXT("SysPathMgr::init: could not create directory '") + _root + NTEXT("'")); return -1; } // update the file attributes with another call to get info in the directory FileUtils::getAttributes( _root, fattrs ); } if (!fattrs.isDirectory()) { CBLOGERR(_logger, NTEXT("SysPathMgr::init: found a file where a directory '") + _root + NTEXT("' was expected")); return -1; } // put a special key with the root attribute in the map _paths[ SYS_PATH_IND + SYS_PATH_ROOTATTR ] = _root; // ok to this point, no errors res = 0; // iterate through the list of child elements whose tag is SYS_PATH_ENTRY // and get the name attribute and value. If all is found properly, then // construct a counter whose value is retrieved from the config node DOMNodeList* children = DomUtils::getNodeList( (const DOMElement*)config, SYS_PATH_ENTRY ); if ( children != NULL ) { for ( XMLSize_t i = 0, sz = children->getLength() ; i < sz; i++ ) { DOMNode* child = children->item(i); if ( (child != NULL) && (child->getNodeType() == DOMNode::ELEMENT_NODE) ) { String value; Mapping attrs; bool found = DomUtils::getNodeValue( (const DOMElement*)child, &value, &attrs ); if ( found ) { res = 0; String tagName; attrs.getIfAvailable(SYS_PATH_TAGATTR, tagName); if ( tagName.length() > 0 ) { add( tagName, value ); } } } } } } return res; }
__global__ void kernelParticleDensity(ParBox pb, DataBox<PitchedBox<Type_, DIM2> > image, DataSpace<DIM2> transpose, int slice, uint32_t globalOffset, uint32_t sliceDim, Mapping mapper) { typedef typename ParBox::FrameType FRAME; typedef typename MappingDesc::SuperCellSize Block; __shared__ FRAME *frame; __shared__ bool isValid; __syncthreads(); /*wait that all shared memory is initialised*/ bool isImageThread = false; const DataSpace<simDim> threadId(threadIdx); const DataSpace<DIM2> localCell(threadId[transpose.x()], threadId[transpose.y()]); const DataSpace<simDim> block = mapper.getSuperCellIndex(DataSpace<simDim > (blockIdx)); const DataSpace<simDim> blockOffset((block - 1) * Block::getDataSpace()); int localId = threadIdx.z * Block::x * Block::y + threadIdx.y * Block::x + threadIdx.x; if (localId == 0) isValid = false; __syncthreads(); //\todo: guard size should not be set to (fixed) 1 here const DataSpace<simDim> realCell(blockOffset + threadId); //delete guard from cell idx #if(SIMDIM==DIM3) uint32_t globalCell = realCell[sliceDim] + globalOffset; if (globalCell == slice) #endif { isValid = true; isImageThread = true; } __syncthreads(); if (!isValid) return; /*index in image*/ DataSpace<DIM2> imageCell( realCell[transpose.x()], realCell[transpose.y()]); // counter is always DIM2 typedef DataBox < PitchedBox< float_X, DIM2 > > SharedMem; extern __shared__ float_X shBlock[]; __syncthreads(); /*wait that all shared memory is initialised*/ const DataSpace<simDim> blockSize(blockDim); SharedMem counter(PitchedBox<float_X, DIM2 > ((float_X*) shBlock, DataSpace<DIM2 > (), blockSize[transpose.x()] * sizeof (float_X))); if (isImageThread) { counter(localCell) = float_X(0.0); } if (localId == 0) { frame = &(pb.getFirstFrame(block, isValid)); } __syncthreads(); while (isValid) //move over all Frames { PMACC_AUTO(particle, (*frame)[localId]); if (particle[multiMask_] == 1) { int cellIdx = particle[localCellIdx_]; // we only draw the first slice of cells in the super cell (z == 0) const DataSpace<simDim> particleCellId(DataSpaceOperations<simDim>::template map<Block > (cellIdx)); #if(SIMDIM==DIM3) uint32_t globalParticleCell = particleCellId[sliceDim] + globalOffset + blockOffset[sliceDim]; if (globalParticleCell == slice) #endif { const DataSpace<DIM2> reducedCell(particleCellId[transpose.x()], particleCellId[transpose.y()]); atomicAddWrapper(&(counter(reducedCell)), particle[weighting_] / NUM_EL_PER_PARTICLE); } } __syncthreads(); if (localId == 0) { frame = &(pb.getNextFrame(*frame, isValid)); } __syncthreads(); } if (isImageThread) { image(imageCell) = (Type_) counter(localCell); } }