bool IVSCC_smoothing_swc::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback, QWidget * parent) { if (func_name == tr("smooth_swc")) { cout<<"Welcome to resample_swc"<<endl; vector<char*>* inlist = (vector<char*>*)(input.at(0).p); vector<char*>* outlist = NULL; vector<char*>* paralist = NULL; if(input.size() != 2) { printf("Please specify both input file and step length parameter.\n"); return false; } paralist = (vector<char*>*)(input.at(1).p); if (paralist->size()!=1) { printf("Please specify only two parameters.\n"); return false; } double length = atof(paralist->at(0)); QString fileOpenName = QString(inlist->at(0)); QString fileSaveName; if (output.size()==0) { printf("No outputfile specified.\n"); fileSaveName = fileOpenName + QString("_Z_T%1.swc").arg(length); } else if (output.size()==1) { outlist = (vector<char*>*)(output.at(0).p); fileSaveName = QString(outlist->at(0)); } else { printf("You have specified more than 1 output file.\n"); return false; } vector<MyMarker*> inswc; if (fileOpenName.toUpper().endsWith(".SWC") || fileOpenName.toUpper().endsWith(".ESWC")) inswc = readSWC_file(fileOpenName.toStdString()); unsigned char* inimg1d = 0; vector<HierarchySegment*> topo_segs; swc2topo_segs(inswc, topo_segs, 1, inimg1d, 0, 0, 0); cout<<"Smooth the final curve"<<endl; for(int i = 0; i < topo_segs.size(); i++) { HierarchySegment * seg = topo_segs[i]; MyMarker * leaf_marker = seg->leaf_marker; MyMarker * root_marker = seg->root_marker; vector<MyMarker*> seg_markers; MyMarker * p = leaf_marker; while(p != root_marker) { seg_markers.push_back(p); p = p->parent; } seg_markers.push_back(root_marker); smooth_curve_Z(seg_markers, length); // smooth_curve_XY(seg_markers, length); } inswc.clear(); topo_segs2swc(topo_segs, inswc, 0); saveSWC_file(fileSaveName.toStdString(), inswc); for(int i = 0; i < inswc.size(); i++) delete inswc[i]; return true; } else if (func_name == tr("help")) { v3d_msg("To be implemented."); } else return false; return true; }
bool consensus_swc_func(const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 &callback) { if(input.size()==0 || output.size() != 1) return false; char * paras = NULL; //parsing input vector<char *> * inlist = (vector<char*> *)(input.at(0).p); if (inlist->size()==0) { cerr<<"You must specify input linker or swc files"<<endl; return false; } //parsing output vector<char *> * outlist = (vector<char*> *)(output.at(0).p); if (outlist->size()>1) { cerr << "You cannot specify more than 1 output files"<<endl; return false; } //parsing parameters int method_code = 1; //adj matrix int cluster_distance_threshold = 5; // ignore nodes that far away for clustering if (input.size()==2) { vector<char*> * paras = (vector<char*> *)(input.at(1).p); if (paras->size() >= 1) { method_code = atoi(paras->at(0)); cout<<"method_code = "<<method_code<<endl; if (paras->size() == 2) { cluster_distance_threshold = atoi(paras->at(1)); cout<<"clustering distance threshold = "<<cluster_distance_threshold<<endl; } } else { cerr<<"Too many parameters"<<endl; return false; } } vector<NeuronTree> nt_list; QStringList nameList; QString qs_linker; char * dfile_result = NULL; V3DLONG neuronNum = 0; for (int i=0; i<inlist->size(); i++) { qs_linker = QString(inlist->at(i)); if (qs_linker.toUpper().endsWith(".ANO")) { cout<<"(0). reading a linker file."<<endl; P_ObjectFileType linker_object; if (!loadAnoFile(qs_linker,linker_object)) { fprintf(stderr,"Error in reading the linker file.\n"); return 1; } nameList = linker_object.swc_file_list; neuronNum += nameList.size(); for (V3DLONG i=0; i<neuronNum; i++) { NeuronTree tmp = readSWC_file(nameList.at(i)); nt_list.push_back(tmp); } } else if (qs_linker.toUpper().endsWith(".SWC")) { cout<<"(0). reading an swc file"<<endl; NeuronTree tmp = readSWC_file(qs_linker); nt_list.push_back(tmp); neuronNum++; if (outlist->size()==0) { cerr<<"You must specify outfile name if you input a list of swcs"<<endl; return false; } } } QString outfileName; if (outlist->size()==0) outfileName = qs_linker + "_consensus.swc"; else outfileName = QString(outlist->at(0)); QList<NeuronSWC> merge_result; if (!consensus_skeleton(nt_list, merge_result, method_code,cluster_distance_threshold, callback)) { cerr<<"error in consensus_skeleton"<<endl; return false; } export_listNeuron_2swc(merge_result,qPrintable(outfileName)); printf("\t %s has been generated successfully, size:%d.\n",qPrintable(outfileName), merge_result.size()); return true; }
bool standardize::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback, QWidget * parent) { vector<char*> infiles, inparas, outfiles; if(input.size() >= 1) infiles = *((vector<char*> *)input.at(0).p); if(input.size() >= 2) inparas = *((vector<char*> *)input.at(1).p); if(output.size() >= 1) outfiles = *((vector<char*> *)output.at(0).p); if (func_name == tr("standardize")) { cout<<"This is standardize_swc plugin"<<endl; if(infiles.size() <2) { cerr<<"Need both the reference swc file ( to seed the soma) and the input swc file."<<endl; cerr<<"You can use the input swc file as the reference swc file, if no particular soma location is required." <<endl; return false; } QString ref_swc_file = infiles[0]; QString inputswc_file = infiles[1]; if(inputswc_file.isEmpty() || ref_swc_file.isEmpty()) { cerr<<"please check both input swc files"<<endl; return false; } if (inparas.size() <1) { printf("Please specify two parameters - 1)the gap size for bridging during the sorting step; 2) the type to be assgined.\n"); return false; } double dis_th = atof(inparas.at(0)); int type = -1;//use the old type if (inparas.size() ==2) type = atof(inparas.at(1)); double sort_th = dis_th ; //the parameter in sort_neuron_swc plugin, specifying the length threshold to bridge the gap QString outswc_file = outfiles[0]; cout<<"ref_swc_file = "<<ref_swc_file.toStdString().c_str()<<endl; cout<<"inswc_file = "<<inputswc_file.toStdString().c_str()<<endl; cout<<"gap threshold = "<<dis_th<<endl; cout<<"outswc_file = "<<outswc_file.toStdString().c_str()<<endl; cout<<"new type code = "<<type<<endl; NeuronTree nt_input = readSWC_file(inputswc_file); // cout<<" Standardize: 1) resample"<<endl; // NeuronTree nt_input_rs = resample(nt_input, dis_th); NeuronTree nt_ref = readSWC_file(ref_swc_file); double soma_x, soma_y, soma_z, soma_r; for (V3DLONG i = 0; i < nt_ref.listNeuron.size(); i++) { if(nt_ref.listNeuron[i].pn<0) { soma_x = nt_ref.listNeuron.at(i).x; soma_y = nt_ref.listNeuron.at(i).y; soma_z = nt_ref.listNeuron.at(i).z; soma_r = nt_ref.listNeuron.at(i).r; break; } } V3DLONG neuronNum = nt_input.listNeuron.size(); QVector<QVector<V3DLONG> > children_list = QVector< QVector<V3DLONG> >(neuronNum, QVector<V3DLONG>() ); for (V3DLONG i = 0; i < neuronNum; i++) { V3DLONG parent = nt_input.listNeuron[i].pn; if (parent < 0) continue; children_list[nt_input.hashNeuron.value(parent)].push_back(i); } double Dist = INT_MAX; double Dist_inrange = INT_MAX; V3DLONG soma_ID = -1; V3DLONG dist_ID = -1; int child_num = 0; cout<<" standardize: 1) matching soma roots"<<endl; // set the distance threshold to searching for matching soma node QList<NeuronSWC> list_neurons = nt_input.listNeuron; double search_distance_th = soma_r * 5 ;// choose the bigger value between soma_r*5 and search_distance_th*5 if (search_distance_th < sort_th *5) { search_distance_th = sort_th *5; } for (V3DLONG i=0;i<list_neurons.size();i++) { NeuronSWC curr = list_neurons.at(i); double nodedist = sqrt(pow2(curr.x - soma_x) + pow2(curr.y - soma_y) + pow2(curr.z - soma_z)); if(nodedist <= search_distance_th && curr.pn <0) { soma_ID = curr.n; child_num = 1; break; } if(nodedist <= search_distance_th && children_list[i].size() > child_num) { soma_ID = curr.n; child_num = children_list[i].size(); Dist_inrange = nodedist; } if(nodedist <= search_distance_th && children_list[i].size() == child_num && nodedist < Dist_inrange) { soma_ID = curr.n; Dist_inrange = nodedist; } if(nodedist < Dist) { dist_ID = curr.n; Dist = nodedist; } } if(child_num < 1 || soma_ID == -1) soma_ID = dist_ID; cout<<" Standardize: 2) sort"<<endl; QList<NeuronSWC> result; if (!SortSWC(nt_input.listNeuron, result ,soma_ID, sort_th)) { v3d_msg("fail to call swc sorting function.",0); return false; } cout<<" Standardize: 3) only keep the first tree(identified by the soma from the reference."<<endl; //skip the first root for (V3DLONG i = 1;i<result.size();i++) { if (result[i].pn == -1) {//remove other trees, only keep the first one cout<< "remove "<<result.size()-i<<" nodes"<<endl; result.erase(result.begin()+i, result.end()); } } cout<<" Standardize: 4) reset type for soma and neurites"<<endl; //1-soma //2-axon //3-dendrite //4-apical dendrite export_list2file_retype(result,outswc_file,0,type); } else if (func_name == tr("help")) { cout << "This super-plugin is used to post-processing auto reconstructions for comparisons. "<<endl; cout << "It will identify the soma for each input reconstruction " <<endl; cout << "based on the reference SWC file, and sort SWC nodes based on the soma root while bridging" <<endl; cout << "all disconneted components when the gap is less then the specified gap_threshold. The search range "<<endl; cout << "for the matching soma is 5*soma_radius." <<endl; cout << "Usage : <vaa3d> -x standardize -f standardize -i <reference_swc_file> <inswc_file> -o <outswc_file> -p <gap_threshold> <new_neurite_type> "<<endl; } else return false; return true; }