int main(int argc, char *argv[]) { RangeList rl; rl.addRangeFile("RangeList_test_input"); std::string range; for (unsigned int i = 0; i < rl.size(); i++) { rl.obtainRange(i, &range); printf("%s\n", range.c_str()); } std::string s = "a b\"MID\" c d"; std::vector<std::string> result; unsigned int ret = stringTokenize(s, ' ', &result); printf("ret = %d\n", ret); dumpStringVector(result); ret = stringTokenize(s, "\" ", &result); printf("ret = %d\n", ret); dumpStringVector(result); s = ""; ret = stringTokenize(s, " ", &result); printf("ret = %d\n", ret); dumpStringVector(result); return 0; }
unsigned int Range::length(void) { // Total number of values specified by a list unsigned int size = 0; RangeList list = rangeList; while(list) { size += list->n_pts(); list = list->next; } return size; }
void serializeRanges(const RangeList &list, std::string &out) { std::ostringstream outs; for (RangeList::const_iterator liter = list.begin(); liter != list.end(); ++liter) { cache_ssize_type len = (cache_ssize_type)((*liter).length()); if ((*liter).goesToEndOfFile()) { len = -len; } outs << (*liter).startbyte() << " " << len << "; "; } out = outs.str(); }
inline bool contains(CallNo callNo, CallFlags callFlags = FREQUENCY_ALL) const { if (empty()) { return false; } RangeList::const_iterator it; for (it = ranges.begin(); it != ranges.end() && it->start <= callNo; ++it) { if (it->contains(callNo, callFlags)) { return true; } } return false; }
static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) { int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes int stride = p->getStride()?p->getStride():attribSize; int start = p->getBufferOffset()+first*attribSize; if(!p->getStride()) { list.addRange(Range(start,count*attribSize)); } else { for(int i = 0 ;i < count; i++,start+=stride) { list.addRange(Range(start,attribSize)); } } }
void CachedView<View>::cache(Space& home) { _firstRange->dispose(home,_lastRange); ViewRanges<View> xr(x); _firstRange = new (home) RangeList(xr.min(),xr.max(),NULL); ++xr; RangeList* cur = _firstRange; for (; xr(); ++xr) { RangeList* next = new (home) RangeList(xr.min(),xr.max(),NULL); cur->next(next); cur = next; } _lastRange = cur; _size = x.size(); }
// Subtract a given range from each element in the list. void HexagonBlockRanges::RangeList::subtract(const IndexRange &Range) { // Cannot assume that the list is unionized (i.e. contains only non- // overlapping ranges. RangeList T; for (iterator Next, I = begin(); I != end(); I = Next) { IndexRange &Rg = *I; if (Rg.overlaps(Range)) { T.addsub(Rg, Range); Next = this->erase(I); } else { Next = std::next(I); } } include(T); }
bool DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr, RangeList &range_list) { range_list.Clear(); uint32_t range_offset = *offset_ptr; const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data(); uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); if (!begin && !end) { // End of range list break; } // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits // of ones switch (addr_size) { case 2: if (begin == 0xFFFFull) begin = DW_INVALID_ADDRESS; break; case 4: if (begin == 0xFFFFFFFFull) begin = DW_INVALID_ADDRESS; break; case 8: break; default: assert(!"DWARFDebugRanges::RangeList::Extract() unsupported address size."); break; } // Filter out empty ranges if (begin < end) range_list.Append(Range(begin, end - begin)); } // Make sure we consumed at least something return range_offset != *offset_ptr; }
/** Adds a parameter to a light curve specification if the appropriate * command line argument was used * * @param[in] range the @ref models::RangeList "RangeList" to update * @param[in] paramName the name of the parameter * @param[in] paramValue the command-line argument to translate into a range * @param[in] distrib the distribution values follow within the range * * @post If @p paramValue was specified on the command line, the corresponding * parameter range is added to @p range. Otherwise, @p range is unchanged. * * @exception lcmc::utils::except::UnexpectedNan Thrown if either element of * @p paramValue is NaN * @exception lcmc::stats::except::ExtraParam Thrown if a value for the parameter is * already in the list * @exception lcmc::stats::except::NegativeRange Thrown if * @p paramValue.second > @p paramValue.first * @exception std::invalid_argument Thrown if @p distrib is not a valid value. * * @exception std::bad_alloc Thrown if there is not enough memory to * add an element to the list. * * @exceptsafe The arguments are unchanged in the event of an exception. */ void addParam(RangeList& range, const ParamType& paramName, ValueArg< std::pair<double, double> >& paramValue, RangeList::RangeType distrib) { if (paramValue.isSet()) { range.add(paramName, paramValue.getValue(), distrib); } }
void Subtitle::joinLines(const RangeList &ranges) { beginCompositeAction(i18n("Join Lines")); RangeList obsoletedRanges; for(RangeList::ConstIterator rangesIt = ranges.begin(), end = ranges.end(); rangesIt != end; ++rangesIt) { int rangeStart = (*rangesIt).start(); int rangeEnd = normalizeRangeIndex((*rangesIt).end()); if(rangeStart >= rangeEnd) continue; SubtitleLine *firstLine = m_lines.at(rangeStart); SubtitleLine *lastLine = m_lines.at(rangeEnd); SString primaryText, secondaryText; for(SubtitleIterator it(*this, Range(rangeStart, rangeEnd - 1)); it.current(); ++it) { if(!it.current()->primaryText().isEmpty()) { primaryText.append(it.current()->primaryText()); primaryText.append("\n"); } if(!it.current()->secondaryText().isEmpty()) { secondaryText.append(it.current()->secondaryText()); secondaryText.append("\n"); } } primaryText.append(lastLine->primaryText()); secondaryText.append(lastLine->secondaryText()); firstLine->setTexts(primaryText, secondaryText); firstLine->setHideTime(lastLine->hideTime()); obsoletedRanges << Range(rangeStart + 1, rangeEnd); } removeLines(obsoletedRanges, Both); endCompositeAction(); }
void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { RangeList ranges; RangeList conversions; GLushort* conversionIndices = NULL; int attribSize = p->getSize(); int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; char* data = static_cast<char*>(p->getBufferData()); if(p->bufferNeedConversion()) { indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted if(conversions.size()) { // there are some elements to convert conversionIndices = new GLushort[count]; int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,conversionIndices,stride,attribSize); } } if(conversionIndices) delete[] conversionIndices; cArrs.setArr(data,p->getStride(),GL_FLOAT); }
void CachedView<View>::update(Space& home, bool share, CachedView<View>& y) { DerivedView<View>::update(home,share,y); if (y._firstRange) { _firstRange = new (home) RangeList(y._firstRange->min(), y._firstRange->max(),NULL); RangeList* cur = _firstRange; for (RangeList* y_cur = y._firstRange->next(); y_cur != NULL; y_cur = y_cur->next()) { RangeList* next = new (home) RangeList(y_cur->min(),y_cur->max(),NULL); cur->next(next); cur = next; } _lastRange = cur; _size = y._size; } }
int Range::index(int ix) { // Value of ix'th index in list RangeList list = rangeList; int n_pts; int iix = ix; while(list) { n_pts = list->n_pts(); if (iix < n_pts) { return list->start + iix * list->step; } list = list->next; iix -= n_pts; } // fell through! fprintf(stderr, "Error: wanted value %d but list length %d\n", ix, length()); abort(); }
static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) { int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes int stride = p->getStride()?p->getStride():attribSize; int start = p->getBufferOffset(); for(int i=0 ; i < count; i++) { GLushort index = (indices_type == GL_UNSIGNED_SHORT? static_cast<const GLushort*>(indices)[i]: static_cast<const GLubyte*>(indices)[i]); list.addRange(Range(start+index*stride,attribSize)); } }
/** Parses the command line parameters that describe model parameter ranges * * @param[in] cmd The command-line parser used by the program * @param[out] range A rangelist to contain the parameter ranges. * * @exception std::logic_error Thrown if the expected parameters are missing from @p cmd. * * @exceptsafe All arguments are left in valid states in the event * of an exception. */ void parseModelParams(CmdLineInterface& cmd, RangeList& range) { range.clear(); addParam(range, "a", getParam<ValueArg<Range> >(cmd, "amp"), RangeList::LOGUNIFORM); addParam(range, "p", getParam<ValueArg<Range> >(cmd, "period"), RangeList::LOGUNIFORM); // Include default phase if no user input range.add("ph", getParam<ValueArg<Range> >(cmd, "ph").getValue(), RangeList::UNIFORM); addParam(range, "width", getParam<ValueArg<Range> >(cmd, "width"), RangeList::LOGUNIFORM); addParam(range, "width2", getParam<ValueArg<Range> >(cmd, "width2"), RangeList::LOGUNIFORM); addParam(range, "d", getParam<ValueArg<Range> >(cmd, "diffus"), RangeList::LOGUNIFORM); addParam(range, "amp2", getParam<ValueArg<Range> >(cmd, "amp2"), RangeList::LOGUNIFORM); addParam(range, "period2", getParam<ValueArg<Range> >(cmd, "period2"), RangeList::LOGUNIFORM); }
void addRange(const CallRange & range) { if (range.start <= range.stop && range.freq != FREQUENCY_NONE) { if (empty()) { limits.start = range.start; limits.stop = range.stop; } else { if (range.start < limits.start) limits.start = range.start; if (range.stop > limits.stop) limits.stop = range.stop; } RangeList::iterator it = ranges.begin(); while (it != ranges.end() && it->start < range.start) { ++it; } ranges.insert(it, range); } }
void TestDef_fr::testStringInput() { struct data { string in; string out; string o_dmy; Field beg; Field end; } t[] = { { "18Vent\303\264se7", "18 Vent\303\264se 7", "18 Vent 7", 2378198, 2378198 }, { "Frim6", "Frimaire 6", "Frim 6", 2377726, 2377755 }, { "7", "7", "7", 2378031, 2378396 }, { "trav8", "F\303\252te du Travail 8", "3 Comp 8", 2378759, 2378759 }, }; size_t count = sizeof(t) / sizeof(data); m_cal->set_input_format( m_sid, "cdmy" ); m_cal->set_output_format( m_sid, "cdmy" ); for( size_t i = 0 ; i < count ; i++ ) { RangeList rl = m_cal->str_to_rangelist( m_sid, t[i].in ); string str = m_cal->rangelist_to_str( m_sid, rl ); CPPUNIT_ASSERT_EQUAL( t[i].out, str ); if( rl.size() ) { CPPUNIT_ASSERT_EQUAL( t[i].beg, rl[0].jdn1 ); size_t j = rl.size() - 1; CPPUNIT_ASSERT_EQUAL( t[i].end, rl[j].jdn2 ); } } m_cal->set_input_format( m_sid, "dmy" ); m_cal->set_output_format( m_sid, "dmy" ); for( size_t i = 0 ; i < count ; i++ ) { RangeList rl = m_cal->str_to_rangelist( m_sid, t[i].in ); string str = m_cal->rangelist_to_str( m_sid, rl ); CPPUNIT_ASSERT_EQUAL( t[i].o_dmy, str ); if( rl.size() ) { CPPUNIT_ASSERT_EQUAL( t[i].beg, rl[0].jdn1 ); size_t j = rl.size() - 1; CPPUNIT_ASSERT_EQUAL( t[i].end, rl[j].jdn2 ); } } }
int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) { int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes int stride = p->getStride()?p->getStride():attribSize; int offset = p->getBufferOffset(); int n = 0; for(int i=0;i<ranges.size();i++) { int startIndex = (ranges[i].getStart() - offset) / stride; int nElements = ranges[i].getSize()/attribSize; for(int j=0;j<nElements;j++) { indices[n++] = startIndex+j; } } return n; }
forceinline void ValSet::update(Space& home, bool share, ValSet& vs) { (void) share; if (vs.n > 0) { n = vs.n; // Count number of ranges int m = 0; for (RangeList* c = vs.fst; c != NULL; c = c->next()) m++; fst = home.alloc<RangeList>(m); lst = fst + (m-1); int i=0; for (RangeList* c = vs.fst; c != NULL; c = c->next()) { fst[i].min(c->min()); fst[i].max(c->max()); fst[i].next(fst+i+1); i++; } lst->next(NULL); } }
forceinline void ValSet::add(Space& home, int v) { RangeList* c = fst; RangeList** p = &fst; while (c != NULL) { if (v < c->min()) { if (v+1 == c->min()) { c->min(v); n++; return; } else { *p = new (home) RangeList(v,v,c); n++; return; } } else if (v <= c->max()) { // Value already included return; } else if (v == c->max()+1) { if ((c->next() != NULL) && (v+1 == c->next()->min())) { c->next()->min(c->min()); *p = c->next(); c->dispose(home,c); } else { c->max(v); } n++; return; } else { // FIXME: HOW TO CAST HERE? p = reinterpret_cast<RangeList**>(c->nextRef()); c = *p; } } *p = new (home) RangeList(v,v,NULL); n++; lst = *p; }
int main(int argc, char** argv) { PARSE_PARAMETER(argc, argv); if (FLAG_help) { PARAMETER_HELP(); return 0; } welcome(); PARAMETER_STATUS(); if (FLAG_REMAIN_ARG.size() > 0) { fprintf(stderr, "Unparsed arguments: "); for (unsigned int i = 0; i < FLAG_REMAIN_ARG.size(); i++) { fprintf(stderr, " %s", FLAG_REMAIN_ARG[i].c_str()); } exit(1); } if (!FLAG_outPrefix.size()) FLAG_outPrefix = "rvtest"; if ((FLAG_inVcf.empty() ? 0 : 1) + (FLAG_inBgen.empty() ? 0 : 1) + (FLAG_inKgg.empty() ? 0 : 1) != 1) { fprintf(stderr, "Please provide one type of input file using: --inVcf, --inBgen or " "--inKgg\n"); exit(1); } // check new version if (!FLAG_noweb) { VersionChecker ver; if (ver.retrieveRemoteVersion("http://zhanxw.com/rvtests/version") < 0) { fprintf(stderr, "Retrieve remote version failed, use '--noweb' to skip.\n"); } else { ver.setLocalVersion(VERSION); if (ver.isRemoteVersionNewer()) { fprintf(stderr, "New version of rvtests is available:"); ver.printRemoteContent(); } } } // start logging Logger _logger((FLAG_outPrefix + ".log").c_str()); logger = &_logger; logger->info("Program version: %s", VERSION); logger->infoToFile("Git Version: %s", GIT_VERSION); logger->infoToFile("Parameters BEGIN"); PARAMETER_INSTANCE().WriteToFile(logger->getHandle()); logger->infoToFile("Parameters END"); logger->sync(); // set up multithreading #ifdef _OPENMP if (FLAG_numThread <= 0) { fprintf(stderr, "Invalid number of threads [ %d ], reset to single thread", FLAG_numThread); omp_set_num_threads(1); } else if (FLAG_numThread > omp_get_max_threads()) { int maxThreads = omp_get_max_threads(); fprintf(stderr, "Reduced your specified number of threads to the maximum of system " "limit [ %d ]", maxThreads); omp_set_num_threads(maxThreads); } else if (FLAG_numThread == 1) { // need to set to one thread, otherwise all CPUs may be used omp_set_num_threads(1); } else { logger->info("Set number of threads = [ %d ]", FLAG_numThread); omp_set_num_threads(FLAG_numThread); } #endif // start analysis time_t startTime = time(0); logger->info("Analysis started at: %s", currentTime().c_str()); GenotypeExtractor* ge = NULL; if (!FLAG_inVcf.empty()) { ge = new VCFGenotypeExtractor(FLAG_inVcf); } else if (!FLAG_inBgen.empty()) { ge = new BGenGenotypeExtractor(FLAG_inBgen, FLAG_inBgenSample); } else if (!FLAG_inKgg.empty()) { ge = new KGGGenotypeExtractor(FLAG_inKgg); } else { assert(false); } // set range filters here ge->setRangeList(FLAG_rangeList.c_str()); ge->setRangeFile(FLAG_rangeFile.c_str()); // set people filters here if (FLAG_peopleIncludeID.size() || FLAG_peopleIncludeFile.size()) { ge->excludeAllPeople(); ge->includePeople(FLAG_peopleIncludeID.c_str()); ge->includePeopleFromFile(FLAG_peopleIncludeFile.c_str()); } ge->excludePeople(FLAG_peopleExcludeID.c_str()); ge->excludePeopleFromFile(FLAG_peopleExcludeFile.c_str()); if (!FLAG_siteFile.empty()) { ge->setSiteFile(FLAG_siteFile); logger->info("Restrict analysis based on specified site file [ %s ]", FLAG_siteFile.c_str()); } if (FLAG_siteDepthMin > 0) { ge->setSiteDepthMin(FLAG_siteDepthMin); logger->info("Set site depth minimum to %d", FLAG_siteDepthMin); } if (FLAG_siteDepthMax > 0) { ge->setSiteDepthMax(FLAG_siteDepthMax); logger->info("Set site depth maximum to %d", FLAG_siteDepthMax); } if (FLAG_siteMACMin > 0) { ge->setSiteMACMin(FLAG_siteMACMin); logger->info("Set site minimum MAC to %d", FLAG_siteDepthMin); } if (FLAG_annoType != "") { ge->setAnnoType(FLAG_annoType.c_str()); logger->info("Set annotype type filter to %s", FLAG_annoType.c_str()); } std::vector<std::string> vcfSampleNames; ge->getPeopleName(&vcfSampleNames); logger->info("Loaded [ %zu ] samples from genotype files", vcfSampleNames.size()); DataLoader dataLoader; dataLoader.setPhenotypeImputation(FLAG_imputePheno); dataLoader.setCovariateImputation(FLAG_imputeCov); if (FLAG_multiplePheno.empty()) { dataLoader.loadPhenotype(FLAG_pheno, FLAG_mpheno, FLAG_phenoName); // // load phenotypes // std::map<std::string, double> phenotype; // if (FLAG_pheno.empty()) { // logger->error("Cannot do association when phenotype is missing!"); // return -1; // } // // check if alternative phenotype columns are used // if (!FLAG_mpheno.empty() && !FLAG_phenoName.empty()) { // logger->error("Please specify either --mpheno or --pheno-name"); // return -1; // } // if (!FLAG_mpheno.empty()) { // int col = atoi(FLAG_mpheno); // int ret = loadPedPhenotypeByColumn(FLAG_pheno.c_str(), &phenotype, // col); // if (ret < 0) { // logger->error("Loading phenotype failed!"); // return -1; // } // } else if (!FLAG_phenoName.empty()) { // int ret = loadPedPhenotypeByHeader(FLAG_pheno.c_str(), &phenotype, // FLAG_phenoName.c_str()); // if (ret < 0) { // logger->error("Loading phenotype failed!"); // return -1; // } // } else { // int col = 1; // default use the first phenotype // int ret = loadPedPhenotypeByColumn(FLAG_pheno.c_str(), &phenotype, // col); // if (ret < 0) { // logger->error("Loading phenotype failed!"); // return -1; // } // } // logger->info("Loaded [ %zu ] sample phenotypes.", phenotype.size()); // rearrange phenotypes // drop samples from phenotype or vcf matchPhenotypeAndVCF("missing phenotype", &dataLoader, ge); // // phenotype names (vcf sample names) arranged in the same order as in // VCF // std::vector<std::string> phenotypeNameInOrder; // std::vector<double> // phenotypeInOrder; // phenotype arranged in the same order as in VCF // rearrange(phenotype, vcfSampleNames, &vcfSampleToDrop, // &phenotypeNameInOrder, // &phenotypeInOrder, FLAG_imputePheno); // if (vcfSampleToDrop.size()) { // // exclude this sample from parsing VCF // ge->excludePeople(vcfSampleToDrop); // // output dropped samples // for (size_t i = 0; i < vcfSampleToDrop.size(); ++i) { // if (i == 0) // logger->warn( // "Total [ %zu ] samples are dropped from VCF file due to missing // " // "phenotype", // vcfSampleToDrop.size()); // if (i >= 10) { // logger->warn( // "Skip outputting additional [ %d ] samples with missing " // "phenotypes.", // ((int)vcfSampleToDrop.size() - 10)); // break; // } // logger->warn("Drop sample [ %s ] from VCF file due to missing // phenotype", // (vcfSampleToDrop)[i].c_str()); // } // // logger->warn("Drop %zu sample from VCF file since we don't have // their // // phenotypes", vcfSampleToDrop.size()); // } // if (phenotypeInOrder.size() != phenotype.size()) { // logger->warn( // "Drop [ %d ] samples from phenotype file due to missing genotypes // from " // "VCF files", // (int)(phenotype.size() - phenotypeInOrder.size())); // // We may output these samples by comparing keys of phenotype and // // phenotypeNameInOrder // } dataLoader.loadCovariate(FLAG_cov, FLAG_covName); matchCovariateAndVCF("missing covariate", &dataLoader, ge); // // load covariate // Matrix covariate; // HandleMissingCov handleMissingCov = COVARIATE_DROP; // if (FLAG_imputeCov) { // handleMissingCov = COVARIATE_IMPUTE; // } // if (FLAG_cov.empty() && !FLAG_covName.empty()) { // logger->info("Use phenotype file as covariate file [ %s ]", // FLAG_pheno.c_str()); // FLAG_cov = FLAG_pheno; // } // if (!FLAG_cov.empty()) { // logger->info("Begin to read covariate file."); // std::vector<std::string> columnNamesInCovariate; // std::set<std::string> sampleToDropInCovariate; // int ret = loadCovariate(FLAG_cov.c_str(), phenotypeNameInOrder, // FLAG_covName.c_str(), handleMissingCov, // &covariate, // &columnNamesInCovariate, // &sampleToDropInCovariate); // if (ret < 0) { // logger->error("Load covariate file failed !"); // exit(1); // } // // drop phenotype samples // if (!sampleToDropInCovariate.empty()) { // int idx = 0; // int n = phenotypeNameInOrder.size(); // for (int i = 0; i < n; ++i) { // if (sampleToDropInCovariate.count(phenotypeNameInOrder[i]) != // 0) { // need to drop // continue; // } // phenotypeNameInOrder[idx] = phenotypeNameInOrder[i]; // phenotypeInOrder[idx] = phenotypeInOrder[i]; // idx++; // } // phenotypeNameInOrder.resize(idx); // phenotypeInOrder.resize(idx); // logger->warn( // "[ %zu ] sample phenotypes are dropped due to lacking // covariates.", // sampleToDropInCovariate.size()); // } // // drop vcf samples; // for (std::set<std::string>::const_iterator iter = // sampleToDropInCovariate.begin(); // iter != sampleToDropInCovariate.end(); ++iter) { // ge->excludePeople(iter->c_str()); // } // } } else { dataLoader.loadMultiplePhenotype(FLAG_multiplePheno, FLAG_pheno, FLAG_cov); matchPhenotypeAndVCF("missing phenotype", &dataLoader, ge); matchCovariateAndVCF("missing covariate", &dataLoader, ge); } dataLoader.loadSex(); if (FLAG_sex) { dataLoader.useSexAsCovariate(); matchCovariateAndVCF("missing sex", &dataLoader, ge); } // // load sex // std::vector<int> sex; // if (loadSex(FLAG_pheno, phenotypeNameInOrder, &sex)) { // logger->error("Cannot load sex of samples from phenotype file"); // exit(1); // } // if (FLAG_sex) { // append sex in covariate // std::vector<int> index; // mark missing samples // int numMissing = findMissingSex(sex, &index); // logger->info("Futher exclude %d samples with missing sex", numMissing); // removeByIndex(index, &sex); // excludeSamplesByIndex(index, &ge, &phenotypeNameInOrder, // &phenotypeInOrder, // &covariate); // appendToMatrix("Sex", sex, &covariate); // } if (!FLAG_condition.empty()) { dataLoader.loadMarkerAsCovariate(FLAG_inVcf, FLAG_condition); matchCovariateAndVCF("missing in conditioned marker(s)", &dataLoader, ge); } // // load conditional markers // if (!FLAG_condition.empty()) { // Matrix geno; // std::vector<std::string> rowLabel; // if (loadMarkerFromVCF(FLAG_inVcf, FLAG_condition, &rowLabel, &geno) < 0) // { // logger->error("Load conditional markers [ %s ] from [ %s ] failed.", // FLAG_condition.c_str(), FLAG_inVcf.c_str()); // exit(1); // } // if (appendGenotype(&covariate, phenotypeNameInOrder, geno, rowLabel) < 0) // { // logger->error( // "Failed to combine conditional markers [ %s ] from [ %s ] failed.", // FLAG_condition.c_str(), FLAG_inVcf.c_str()); // exit(1); // } // } dataLoader.checkConstantCovariate(); // // check if some covariates are constant for all samples // // e.g. user may include covariate "1" in addition to intercept // // in such case, we will give a fatal error // for (int i = 0; i < covariate.cols; ++i) { // std::set<double> s; // s.clear(); // for (int j = 0; j < covariate.rows; ++j) { // s.insert(covariate(j,i)); // } // if (s.size() == 1) { // logger->error( // "Covariate [ %s ] equals [ %g ] for all samples, cannot fit " // "model...\n", // covariate.GetColumnLabel(i), *s.begin()); // exit(1); // } // } g_SummaryHeader = new SummaryHeader; g_SummaryHeader->recordCovariate(dataLoader.getCovariate()); // record raw phenotype g_SummaryHeader->recordPhenotype("Trait", dataLoader.getPhenotype().extractCol(0)); // adjust phenotype // bool binaryPhenotype; if (FLAG_qtl) { // binaryPhenotype = false; dataLoader.setTraitType(DataLoader::PHENOTYPE_QTL); logger->info("-- Force quantitative trait mode -- "); } else { if (dataLoader.detectPhenotypeType() == DataLoader::PHENOTYPE_BINARY) { logger->warn("-- Enabling binary phenotype mode -- "); dataLoader.setTraitType(DataLoader::PHENOTYPE_BINARY); } else { dataLoader.setTraitType(DataLoader::PHENOTYPE_QTL); } // binaryPhenotype = isBinaryPhenotype(phenotypeInOrder); // if (binaryPhenotype) { // logger->warn("-- Enabling binary phenotype mode -- "); // convertBinaryPhenotype(&phenotypeInOrder); // } } if (FLAG_useResidualAsPhenotype) { dataLoader.useResidualAsPhenotype(); g_SummaryHeader->recordEstimation(dataLoader.getEstimation()); } // // use residual as phenotype // if (FLAG_useResidualAsPhenotype) { // if (binaryPhenotype) { // logger->warn( // "WARNING: Skip transforming binary phenotype, although you want to // " // "use residual as phenotype!"); // } else { // if (covariate.cols > 0) { // LinearRegression lr; // Vector pheno; // Matrix covAndInt; // copy(phenotypeInOrder, &pheno); // copyCovariateAndIntercept(covariate.rows, covariate, &covAndInt); // if (!lr.FitLinearModel(covAndInt, pheno)) { // logger->error( // "Cannot fit model: [ phenotype ~ 1 + covariates ], now use the // " // "original phenotype"); // } else { // const int n = lr.GetResiduals().Length(); // for (int i = 0; i < n; ++i) { // phenotypeInOrder[i] = lr.GetResiduals()[i]; // } // covariate.Dimension(0, 0); // logger->info( // "DONE: Fit model [ phenotype ~ 1 + covariates ] and model " // "residuals will be used as responses."); // } // } else { // no covaraites // centerVector(&phenotypeInOrder); // logger->info("DONE: Use residual as phenotype by centerng it"); // } // } // } if (FLAG_inverseNormal) { dataLoader.inverseNormalizePhenotype(); g_SummaryHeader->setInverseNormalize(FLAG_inverseNormal); } // // phenotype transformation // if (FLAG_inverseNormal) { // if (binaryPhenotype) { // logger->warn( // "WARNING: Skip transforming binary phenotype, although you required // " // "inverse normalization!"); // } else { // logger->info("Now applying inverse normalize transformation."); // inverseNormalizeLikeMerlin(&phenotypeInOrder); // g_SummaryHeader->setInverseNormalize(FLAG_inverseNormal); // logger->info("DONE: inverse normalization transformation finished."); // } // } g_SummaryHeader->recordPhenotype("AnalyzedTrait", dataLoader.getPhenotype().extractCol(0)); if (dataLoader.getPhenotype().nrow() == 0) { logger->fatal("There are 0 samples with valid phenotypes, quitting..."); exit(1); } // if (phenotypeInOrder.empty()) { // logger->fatal("There are 0 samples with valid phenotypes, quitting..."); // exit(1); // } logger->info("Analysis begins with [ %d ] samples...", dataLoader.getPhenotype().nrow()); ////////////////////////////////////////////////////////////////////////////// // prepare each model bool singleVariantMode = FLAG_modelSingle.size() || FLAG_modelMeta.size(); bool groupVariantMode = (FLAG_modelBurden.size() || FLAG_modelVT.size() || FLAG_modelKernel.size()); if (singleVariantMode && groupVariantMode) { logger->error("Cannot support both single variant and region based tests"); exit(1); } ModelManager modelManager(FLAG_outPrefix); // set up models in qtl/binary modes if (dataLoader.isBinaryPhenotype()) { modelManager.setBinaryOutcome(); matchPhenotypeAndVCF("missing phenotype (not case/control)", &dataLoader, ge); } else { modelManager.setQuantitativeOutcome(); } // create models modelManager.create("single", FLAG_modelSingle); modelManager.create("burden", FLAG_modelBurden); modelManager.create("vt", FLAG_modelVT); modelManager.create("kernel", FLAG_modelKernel); modelManager.create("meta", FLAG_modelMeta); if (FLAG_outputRaw) { modelManager.create("outputRaw", "dump"); } const std::vector<ModelFitter*>& model = modelManager.getModel(); const std::vector<FileWriter*>& fOuts = modelManager.getResultFile(); const size_t numModel = model.size(); // TODO: optimize this to avoid data copying Matrix phenotypeMatrix; Matrix covariate; toMatrix(dataLoader.getPhenotype(), &phenotypeMatrix); toMatrix(dataLoader.getCovariate(), &covariate); // determine VCF file reading pattern // current support: // * line by line ( including range selection) // * gene by gene // * range by range std::string rangeMode = "Single"; if (FLAG_geneFile.size() && (FLAG_setFile.size() || FLAG_setList.size())) { logger->error("Cannot specify both gene file and set file."); exit(1); } if (!FLAG_gene.empty() && FLAG_geneFile.empty()) { logger->error("Please provide gene file for gene bases analysis."); exit(1); } OrderedMap<std::string, RangeList> geneRange; if (FLAG_geneFile.size()) { rangeMode = "Gene"; int ret = loadGeneFile(FLAG_geneFile.c_str(), FLAG_gene.c_str(), &geneRange); if (ret < 0 || geneRange.size() == 0) { logger->error("Error loading gene file or gene list is empty!"); return -1; } else { logger->info("Loaded [ %zu ] genes.", geneRange.size()); } } if (!FLAG_set.empty() && FLAG_setFile.empty()) { logger->error("Please provide set file for set bases analysis."); exit(1); } if (FLAG_setFile.size()) { rangeMode = "Range"; int ret = loadRangeFile(FLAG_setFile.c_str(), FLAG_set.c_str(), &geneRange); if (ret < 0 || geneRange.size() == 0) { logger->error("Error loading set file or set list is empty!"); return -1; } else { logger->info("Loaded [ %zu ] set to tests.", geneRange.size()); } } if (FLAG_setList.size()) { rangeMode = "Range"; int ret = appendListToRange(FLAG_setList, &geneRange); if (ret < 0) { logger->error("Error loading set list or set list is empty!"); return -1; } } DataConsolidator dc; dc.setSex(&dataLoader.getSex()); dc.setFormula(&dataLoader.getFormula()); dc.setGenotypeCounter(ge->getGenotypeCounter()); // load kinshp if needed by family models if (modelManager.hasFamilyModel() || (!FLAG_modelMeta.empty() && !FLAG_kinship.empty())) { logger->info("Family-based model specified. Loading kinship file..."); // process auto kinship if (dc.setKinshipSample(dataLoader.getPhenotype().getRowName()) || dc.setKinshipFile(DataConsolidator::KINSHIP_AUTO, FLAG_kinship) || dc.setKinshipEigenFile(DataConsolidator::KINSHIP_AUTO, FLAG_kinshipEigen) || dc.loadKinship(DataConsolidator::KINSHIP_AUTO)) { logger->error( "Failed to load autosomal kinship (you may use vcf2kinship to " "generate one)."); exit(1); } if (dc.setKinshipFile(DataConsolidator::KINSHIP_X, FLAG_xHemiKinship) || dc.setKinshipEigenFile(DataConsolidator::KINSHIP_X, FLAG_xHemiKinshipEigen) || dc.loadKinship(DataConsolidator::KINSHIP_X)) { logger->warn( "Autosomal kinship loaded, but no hemizygote region kinship " "provided, some sex chromosome tests will be skipped."); // keep the program going } } else if (!FLAG_kinship.empty() && FLAG_modelMeta.empty()) { logger->info( "Family-based model not specified. Options related to kinship will be " "ignored here."); } // set imputation method if (FLAG_impute.empty()) { logger->info("Impute missing genotype to mean (by default)"); dc.setStrategy(DataConsolidator::IMPUTE_MEAN); } else if (FLAG_impute == "mean") { logger->info("Impute missing genotype to mean"); dc.setStrategy(DataConsolidator::IMPUTE_MEAN); } else if (FLAG_impute == "hwe") { logger->info("Impute missing genotype by HWE"); dc.setStrategy(DataConsolidator::IMPUTE_HWE); } else if (FLAG_impute == "drop") { logger->info("Drop missing genotypes"); dc.setStrategy(DataConsolidator::DROP); } dc.setPhenotypeName(dataLoader.getPhenotype().getRowName()); // set up par region ParRegion parRegion(FLAG_xLabel, FLAG_xParRegion); dc.setParRegion(&parRegion); // genotype will be extracted and stored if (FLAG_freqUpper > 0) { ge->setSiteFreqMax(FLAG_freqUpper); logger->info("Set upper minor allele frequency limit to %g", FLAG_freqUpper); } if (FLAG_freqLower > 0) { ge->setSiteFreqMin(FLAG_freqLower); logger->info("Set lower minor allele frequency limit to %g", FLAG_freqLower); } // handle sex chromosome ge->setParRegion(&parRegion); ge->setSex(&dataLoader.getSex()); // use dosage instead GT if (!FLAG_dosageTag.empty()) { ge->setDosageTag(FLAG_dosageTag); logger->info("Use dosage genotype from VCF flag %s.", FLAG_dosageTag.c_str()); } // multi-allelic sites will be treats as ref/alt1, ref/alt2, ref/alt3.. // instead of ref/alt1 (biallelic) if (FLAG_multiAllele) { ge->enableMultiAllelicMode(); logger->info("Enable analysis using multiple allelic models"); } // genotype QC options if (FLAG_indvDepthMin > 0) { ge->setGDmin(FLAG_indvDepthMin); logger->info("Minimum GD set to %d (or marked as missing genotype).", FLAG_indvDepthMin); } if (FLAG_indvDepthMax > 0) { ge->setGDmax(FLAG_indvDepthMax); logger->info("Maximum GD set to %d (or marked as missing genotype).", FLAG_indvDepthMax); } if (FLAG_indvQualMin > 0) { ge->setGQmin(FLAG_indvQualMin); logger->info("Minimum GQ set to %d (or marked as missing genotype).", FLAG_indvQualMin); } // e.g. check colinearity and correlations between predictors dc.preRegressionCheck(phenotypeMatrix, covariate); // prepare PLINK files for BoltLMM model if (!FLAG_boltPlink.empty()) { if (dc.prepareBoltModel(FLAG_boltPlink, dataLoader.getPhenotype().getRowName(), dataLoader.getPhenotype())) { logger->error( "Failed to prepare inputs for BOLT-LMM association test model with " "this prefix [ %s ]!", FLAG_boltPlink.c_str()); exit(1); } } logger->info("Analysis started"); Result& buf = dc.getResult(); Matrix& genotype = dc.getOriginalGenotype(); // we have three modes: // * single variant reading, single variant test // * range variant reading, single variant test // * range variant reading, group variant test if (rangeMode == "Single" && singleVariantMode) { // use line by line mode buf.addHeader("CHROM"); buf.addHeader("POS"); if (FLAG_outputID) { buf.addHeader("ID"); } buf.addHeader("REF"); buf.addHeader("ALT"); buf.addHeader("N_INFORMATIVE"); // output headers for (size_t m = 0; m < model.size(); m++) { model[m]->writeHeader(fOuts[m], buf); } int variantProcessed = 0; while (true) { buf.clearValue(); int ret = ge->extractSingleGenotype(&genotype, &buf); if (ret == GenotypeExtractor::FILE_END) { // reach file end break; } if (ret == GenotypeExtractor::FAIL_FILTER) { continue; } if (ret != GenotypeExtractor::SUCCEED) { logger->error("Extract genotype failed at site: %s:%s!", buf["CHROM"].c_str(), buf["POS"].c_str()); continue; } if (genotype.cols == 0) { logger->warn("Extract [ %s:%s ] has 0 variants, skipping", buf["CHROM"].c_str(), buf["POS"].c_str()); continue; } ++variantProcessed; dc.consolidate(phenotypeMatrix, covariate, genotype); buf.updateValue("N_INFORMATIVE", toString(genotype.rows)); // logger->info("Test variant at site: %s:%s!", // buf["CHROM"].c_str(), buf["POS"].c_str()); // fit each model for (size_t m = 0; m != numModel; m++) { model[m]->reset(); model[m]->fit(&dc); model[m]->writeOutput(fOuts[m], buf); } } logger->info("Analyzed [ %d ] variants", variantProcessed); } else if (rangeMode != "Single" && singleVariantMode) { // read by gene/range model, single variant // test buf.addHeader(rangeMode); buf.addHeader("CHROM"); buf.addHeader("POS"); if (FLAG_outputID) { buf.addHeader("ID"); } buf.addHeader("REF"); buf.addHeader("ALT"); buf.addHeader("N_INFORMATIVE"); // output headers for (size_t m = 0; m < numModel; m++) { model[m]->writeHeader(fOuts[m], buf); } std::string geneName; RangeList rangeList; int variantProcessed = 0; for (size_t i = 0; i < geneRange.size(); ++i) { geneRange.at(i, &geneName, &rangeList); ge->setRange(rangeList); while (true) { buf.clearValue(); int ret = ge->extractSingleGenotype(&genotype, &buf); if (ret == GenotypeExtractor::FILE_END) { // reach end of this region break; } if (ret == GenotypeExtractor::FAIL_FILTER) { continue; } if (ret != GenotypeExtractor::SUCCEED) { logger->error("Extract genotype failed for gene %s!", geneName.c_str()); continue; } if (genotype.cols == 0) { logger->warn("Gene %s has 0 variants, skipping", geneName.c_str()); continue; } ++variantProcessed; dc.consolidate(phenotypeMatrix, covariate, genotype); buf.updateValue(rangeMode, geneName); buf.updateValue("N_INFORMATIVE", genotype.rows); // #pragma omp parallel for for (size_t m = 0; m != numModel; m++) { model[m]->reset(); model[m]->fit(&dc); model[m]->writeOutput(fOuts[m], buf); } } } logger->info("Analyzed [ %d ] variants from [ %d ] genes/regions", variantProcessed, (int)geneRange.size()); } else if (rangeMode != "Single" && groupVariantMode) { // read by gene/range mode, group variant // test buf.addHeader(rangeMode); buf.addHeader("RANGE"); buf.addHeader("N_INFORMATIVE"); buf.addHeader("NumVar"); buf.addHeader("NumPolyVar"); // output headers for (size_t m = 0; m < numModel; m++) { model[m]->writeHeader(fOuts[m], buf); } std::string geneName; RangeList rangeList; int variantProcessed = 0; ge->enableAutoMerge(); for (size_t i = 0; i < geneRange.size(); ++i) { geneRange.at(i, &geneName, &rangeList); ge->setRange(rangeList); buf.clearValue(); int ret = ge->extractMultipleGenotype(&genotype); if (ret != GenotypeExtractor::SUCCEED) { logger->error("Extract genotype failed for gene %s!", geneName.c_str()); continue; } if (genotype.cols == 0) { logger->info("Gene %s has 0 variants, skipping", geneName.c_str()); continue; } variantProcessed += genotype.cols; // genotype is people by marker dc.consolidate(phenotypeMatrix, covariate, genotype); buf.updateValue(rangeMode, geneName); buf.updateValue("RANGE", rangeList.toString()); buf.updateValue("N_INFORMATIVE", genotype.rows); buf.updateValue("NumVar", genotype.cols); buf.updateValue("NumPolyVar", dc.getFlippedToMinorPolymorphicGenotype().cols); // #ifdef _OPENMP // #pragma omp parallel for // #endif for (size_t m = 0; m != numModel; m++) { model[m]->reset(); model[m]->fit(&dc); model[m]->writeOutput(fOuts[m], buf); } } logger->info("Analyzed [ %d ] variants from [ %d ] genes/regions", variantProcessed, (int)geneRange.size()); } else { logger->error( "Unsupported reading mode and test modes! (need more parameters?)"); exit(1); } // Resource cleaning up modelManager.close(); delete g_SummaryHeader; time_t endTime = time(0); logger->info("Analysis ends at: %s", currentTime().c_str()); int elapsedSecond = (int)(endTime - startTime); logger->info("Analysis took %d seconds", elapsedSecond); fputs("RVTESTS finished successfully\n", stdout); return 0; }
Type(const std::string &n, const Range &r) : name(n) { ranges.push_back(r); }
bool GLBndSet::include_full(Space& home, int mi, int ma, SetDelta& d) { assert(ma >= mi); assert(fst() != NULL); RangeList* p = NULL; RangeList* c = fst(); while (c != NULL) { if (c->max() >= mi-1){ if (c->min() > ma+1) { //in a hole before c _size+=(ma-mi+1); d._glbMin = mi; d._glbMax = ma; RangeList* q = new (home) RangeList(mi,ma,c); if (p==NULL) //the new range is the first fst(q); else p->next(q); return true; } //if the range starts before c, update c->min and size bool result = false; if (c->min()>mi) { _size+=(c->min()-mi); c->min(mi); d._glbMin = mi; result = true; } else { d._glbMin = c->max()+1; } assert(c->min()<=mi); assert(c->max()+1>=mi); if (c->max() >= ma) { d._glbMax = c->min()-1; return result; } RangeList* q = c; //sum up the size of holes eaten int prevMax = c->max(); int growth = 0; // invariant: q->min()<=ma+1 while (q->next() != NULL && q->next()->min() <= ma+1) { q = q->next(); growth += q->min()-prevMax-1; prevMax = q->max(); } assert(growth>=0); _size+=growth; if (q->max() < ma) { _size += ma-q->max(); d._glbMax = ma; } else { d._glbMax = q->min()-1; } c->max(std::max(ma,q->max())); if (c!=q) { RangeList* oldCNext = c->next(); assert(oldCNext!=NULL); //q would have stayed c if c was last. c->next(q->next()); if (q->next()==NULL){ assert(q==lst()); lst(c); } oldCNext->dispose(home,q); } return true; } RangeList* nc = c->next(); p=c; c=nc; } //the new range is disjoint from the old domain and we add it as last: assert(mi>max()+1); RangeList* q = new (home) RangeList(mi, ma, NULL); lst()->next(q); lst(q); _size+= q->width(); d._glbMin = mi; d._glbMax = ma; return true; }
bool LUBndSet::exclude_full(Space& home, int mi, int ma, SetDelta& d) { assert(ma >= mi); assert(mi <= max() && ma >= min() && (mi > min() || ma < max())); bool result=false; RangeList* p = NULL; RangeList* c = fst(); d._lubMin = Limits::max+1; while (c != NULL) { if (c->max() >= mi){ if (c->min() > ma) { return result; } //in a hole if (c->min()<mi && c->max() > ma) { //Range split: RangeList* q = new (home) RangeList(ma+1,c->max(),c->next()); c->max(mi-1); if (c == lst()) { lst(q); } c->next(q); _size -= (ma-mi+1); d._lubMin = mi; d._lubMax = ma; return true; } if (c->max() > ma) { //start of range clipped, end remains d._lubMin = std::min(d._lubMin, c->min()); d._lubMax = ma; _size-=(ma-c->min()+1); c->min(ma+1); return true; } if (c->min() < mi) { //end of range clipped, start remains _size-=(c->max()-mi+1); d._lubMin = mi; d._lubMax = c->max(); c->max(mi-1); result=true; } else { //range *c destroyed d._lubMin = c->min(); _size-=c->width(); RangeList *cend = c; while ((cend->next()!=NULL) && (cend->next()->max()<=ma)){ cend = cend->next(); _size-=cend->width(); } d._lubMax = cend->max(); if (fst()==c) { fst(cend->next()); } else { p->next(cend->next()); } if (lst()==cend) { lst(p); } RangeList* nc=cend->next(); //performs loop step! c->dispose(home,cend); p=cend; c=nc; if (c != NULL && c->min() <= ma ) { //start of range clipped, end remains _size-=(ma-c->min()+1); c->min(ma+1); d._lubMax = ma; } return true; } } RangeList *nc = c->next(); p=c; c=nc; } return result; }
bool LUBndSet::intersect_full(Space& home, int mi, int ma) { RangeList* p = NULL; RangeList* c = fst(); assert(c != NULL); // Never intersect with an empty set // Skip ranges that are before mi while (c != NULL && c->max() < mi) { _size -= c->width(); RangeList *nc = c->next(); p=c; c=nc; } if (c == NULL) { // Delete entire domain fst()->dispose(home, lst()); fst(NULL); lst(NULL); return true; } bool changed = false; if (c != fst()) { fst()->dispose(home, p); fst(c); p = NULL; changed = true; } // We have found the first range that intersects with [mi,ma] if (mi > c->min()) { _size -= mi-c->min(); c->min(mi); changed = true; } while (c != NULL && c->max() <= ma) { RangeList *nc = c->next(); p=c; c=nc; } if (c == NULL) return changed; RangeList* newlst = p; if (ma >= c->min()) { _size -= c->max() - ma; c->max(ma); newlst = c; RangeList* nc = c->next(); c->next(NULL); p=c; c=nc; } else if (p != NULL) { p->next(NULL); } if (c != NULL) { for (RangeList* cc = c ; cc != NULL; cc = cc->next()) _size -= cc->width(); c->dispose(home, lst()); } lst(newlst); if (newlst==NULL) fst(NULL); return true; }
void clear() { type = NONE; name.clear(); ranges.clear(); }
void Subtitle::removeLines(const RangeList &r, TextTarget target) { if(m_lines.isEmpty()) return; RangeList ranges = r; ranges.trimToIndex(m_lines.count() - 1); if(ranges.isEmpty()) return; if(target == Both) { beginCompositeAction(i18n("Remove Lines")); RangeList::ConstIterator rangesIt = ranges.end(), begin = ranges.begin(); do { rangesIt--; processAction(new RemoveLinesAction(*this, (*rangesIt).start(), (*rangesIt).end())); } while(rangesIt != begin); endCompositeAction(); } else if(target == Secondary) { beginCompositeAction(i18n("Remove Lines")); RangeList rangesComplement = ranges.complement(); rangesComplement.trimToRange(Range(ranges.firstIndex(), m_lines.count() - 1)); // we have to move the secondary texts up (we do it in chunks) SubtitleIterator srcIt(*this, rangesComplement); SubtitleIterator dstIt(*this, Range::upper(ranges.firstIndex())); for(; srcIt.current() && dstIt.current(); ++srcIt, ++dstIt) dstIt.current()->setSecondaryText(srcIt.current()->secondaryText()); // the remaining lines secondary text must be cleared for(; dstIt.current(); ++dstIt) dstIt.current()->setSecondaryText(SString()); endCompositeAction(); } else { // if target == Primary beginCompositeAction(i18n("Remove Lines"), true, false); RangeList mutableRanges(ranges); mutableRanges.trimToIndex(m_lines.count() - 1); // first, we need to append as many empty lines as we're to remove // we insert them with a greater time than the one of the last (non deleted) line int linesCount = m_lines.count(); Range lastRange = mutableRanges.last(); int lastIndex = lastRange.end() == linesCount - 1 ? lastRange.start() - 1 : linesCount - 1; SubtitleLine *lastLine = lastIndex < linesCount ? m_lines.at(lastIndex) : 0; Time showTime(lastLine ? lastLine->hideTime() + 100 : 0); Time hideTime(showTime + 1000); QList<SubtitleLine *> lines; for(int index = 0, size = ranges.indexesCount(); index < size; ++index) { lines.append(new SubtitleLine(SString(), SString(), showTime, hideTime)); showTime.shift(1100); hideTime.shift(1100); } processAction(new InsertLinesAction(*this, lines)); // then, we move the secondary texts down (we need to iterate from bottom to top for that) RangeList rangesComplement = mutableRanges.complement(); SubtitleIterator srcIt(*this, Range(ranges.firstIndex(), m_lines.count() - lines.count() - 1), true); SubtitleIterator dstIt(*this, rangesComplement, true); for(; srcIt.current() && dstIt.current(); --srcIt, --dstIt) dstIt.current()->setSecondaryText(srcIt.current()->secondaryText()); // finally, we can remove the specified lines RangeList::ConstIterator rangesIt = ranges.end(), begin = ranges.begin(); do { rangesIt--; processAction(new RemoveLinesAction(*this, (*rangesIt).start(), (*rangesIt).end())); } while(rangesIt != begin); endCompositeAction(); } }
forceinline void IntTraceView::prune(Space& home, IntView y, const Delta& d) { if (y.range() && (dom->next() == NULL)) { dom->min(y.min()); dom->max(y.max()); } else if (!y.any(d) && (y.max(d)+1 == y.min())) { // The lower bound has been adjusted if (y.min() > dom->max()) { RangeList* p = dom; RangeList* l = p->next(); while ((l != NULL) && (l->max() < y.min())) { p=l; l=l->next(); } dom->dispose(home,p); dom = l; } dom->min(y.min()); } else if (!y.any(d) && (y.max()+1 == y.min(d))) { // upper bound has been adjusted if ((y.max() <= dom->max()) && (dom->next() == NULL)) { dom->max(y.max()); } else { RangeList* p = dom; RangeList* l = p->next(); while ((l != NULL) && (l->min() <= y.max())) { p=l; l=l->next(); } p->max(y.max()); if (p->next() != NULL) p->next()->dispose(home); p->next(NULL); } } else { // Just copy the domain ViewRanges<IntView> yr(y); RangeList::overwrite(home,dom,yr); } }
unsigned int NSequences(void) const { return ranges.size(); }
// resize - add new (empty) rows at end void AddRows(unsigned int nNewRows) { ranges.resize(ranges.size() + nNewRows); }