/** Obtain coordinates for a line plot through a IMDWorkspace. * Cross the workspace from start to end points, recording the signal along the *line. * Sets the x,y vectors to the histogram bin boundaries and counts * * @param start :: coordinates of the start point of the line * @param end :: coordinates of the end point of the line * @param normalize :: how to normalize the signal * @returns :: a LinePlot in which x is set to the boundaries of the bins, * relative to start of the line, y is set to the normalized signal for * each bin with Length = length(x) - 1 and e is set to the normalized * errors for each bin with Length = length(x) - 1. */ IMDWorkspace::LinePlot IMDWorkspace::getLinePlot(const Mantid::Kernel::VMD &start, const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize) const { // TODO: Don't use a fixed number of points later size_t numPoints = 200; VMD step = (end - start) / double(numPoints); double stepLength = step.norm(); // This will be the curve as plotted LinePlot line; for (size_t i = 0; i < numPoints; i++) { // Coordinate along the line VMD coord = start + step * double(i); // Record the position along the line line.x.push_back(static_cast<coord_t>(stepLength * double(i))); signal_t yVal = this->getSignalAtCoord(coord.getBareArray(), normalize); line.y.push_back(yVal); line.e.push_back(0.0); } // And the last point line.x.push_back((end - start).norm()); return line; }
//Allocate VMD and ensure it is unique according to 'version' and 'mdid'. VMD * UseDefMgr::allocVMD(UINT mdid, UINT version) { ASSERT0(mdid > 0); Vector<VMD*> * vec = m_map_md2vmd.get(mdid); if (vec == NULL) { vec = new Vector<VMD*>(); m_map_md2vmd.set(mdid, vec); } VMD * v = vec->get(version); if (v != NULL) { return v; } ASSERT(m_vmd_pool, ("not init")); v = (VMD*)smpoolMallocConstSize(sizeof(VMD), m_vmd_pool); ASSERT0(v); ::memset(v, 0, sizeof(VMD)); v->init(m_ru->getMiscBitSetMgr()->getSegMgr()); VOPND_code(v) = VOPND_MD; VOPND_id(v) = m_vopnd_count++; VMD_mdid(v) = mdid; VMD_version(v) = version; VMD_def(v) = NULL; vec->set(version, v); m_vopnd_vec.set(v->id(), v); return v; }
//Remove given USE from occurence set. void MDSSAInfo::removeUse(IR const* exp, IN UseDefMgr * usedefmgr) { ASSERT0(exp && exp->is_exp() && usedefmgr); SEGIter * iter = NULL; for (INT i = getVOpndSet()->get_first(&iter); i >= 0; i = getVOpndSet()->get_next(i, &iter)) { VMD * vopnd = (VMD*)usedefmgr->getVOpnd(i); ASSERT0(vopnd && vopnd->is_md()); vopnd->getOccSet()->diff(exp->id()); } }
// //START MDSSAInfo // //Return true if all definition of vopnd can reach 'exp'. bool MDSSAInfo::isUseReachable(IN UseDefMgr * usedefmgr, IR const* exp) { ASSERT0(usedefmgr && exp && exp->is_exp()); SEGIter * iter = NULL; for (INT i = getVOpndSet()->get_first(&iter); i >= 0; i = getVOpndSet()->get_next(i, &iter)) { VMD * vopnd = (VMD*)usedefmgr->getVOpnd(i); ASSERT0(vopnd && vopnd->is_md()); if (!vopnd->getOccSet()->is_contain(exp->id())) { return false; } } return true; }
//Facility function to make it easier to get the VOpnd of operand of PHI. VMD * MDPhi::getOpndVMD(IR const* opnd, UseDefMgr const* mgr) const { ASSERT(xcom::in_list(getOpndList(), opnd), ("not operand of phi")); if (!opnd->is_id() && opnd->isMemoryOpnd()) { return NULL; } ASSERT0(mgr && mgr->getMDSSAInfo(opnd) && mgr->getMDSSAInfo(opnd)->getVOpndSet()->get_elem_count() == 1); SEGIter * iter; VMD * vopnd = (VMD*)mgr->getVOpnd(mgr->getMDSSAInfo(opnd)-> getVOpndSet()->get_first(&iter)); ASSERT0(vopnd->is_md()); return vopnd; }
/** Constructor with N-1 vectors on the plane's surface. * * @param vectors :: vector of N-1 vectors with N dimensions. * @param origin :: any point on the plane * @param insidePoint :: coordinate of a point that is known to be inside the *plane described * @throws if the vectors are collinear */ MDPlane::MDPlane(const std::vector<Mantid::Kernel::VMD> &vectors, const Mantid::Kernel::VMD &origin, const Mantid::Kernel::VMD &insidePoint) { // Get the normal vector by the determinant method VMD normal = VMD::getNormalVector(vectors); // The dimensionality of the plane m_nd = normal.getNumDims(); // Whew. We have a normal, and a point on the plane. We can construct construct(normal, origin); // Did we get the wrong sign of the normal? if (!this->isPointBounded(insidePoint)) { // Flip the normal over delete[] this->m_normal; for (size_t d = 0; d < normal.getNumDims(); d++) normal[d] = -1.0f * normal[d]; // And re-construct construct(normal, origin); } }
//Collect all USE, where USE is IR expression. void MDSSAInfo::collectUse( OUT DefSBitSetCore & set, IN UseDefMgr * usedefmgr, IN DefMiscBitSetMgr * bsmgr) { ASSERT0(usedefmgr && bsmgr); SEGIter * iter = NULL; Region * rg = usedefmgr->getRegion(); for (INT i = getVOpndSet()->get_first(&iter); i >= 0; i = getVOpndSet()->get_next(i, &iter)) { VMD * vopnd = (VMD*)usedefmgr->getVOpnd(i); ASSERT0(vopnd && vopnd->is_md()); SEGIter * vit = NULL; for (INT i2 = vopnd->getOccSet()->get_first(&vit); i2 >= 0; i2 = vopnd->getOccSet()->get_next(i2, &vit)) { IR * use = rg->getIR(i2); ASSERT0(use && (use->isMemoryRef() || use->is_id())); set.bunion(use->id(), *bsmgr); } } }
/** Build a coordinate transformation based on an origin and orthogonal basis vectors. * This can reduce the number of dimensions. For example: * * - The input position is X=(x,y,z) * - The origin is X0=(x0,y0,z0) * - The basis vectors are U and V (reducing from 3 to 2D) * - The output position u = (X-X0).U = X.U - X0.U = x*Ux + y*Uy + z*Uz + (X0.U) * - The output position v = (X-X0).V = X.V - X0.V = x*Vx + y*Vy + z*Vz + (X0.V) * * And this allows us to create the affine matrix: * * | Ux Uy Uz X0.U | | x | | u | * | Vx Vy Vz X0.V | | y | = | v | * | 0 0 0 1 | | z | | 1 | * | 1 | * * @param origin :: origin (in the inDimension), which corresponds to (0,0,...) in outD * @param axes :: a list of basis vectors. There must be outD vectors (one for each output dimension) * and each vector must be of length inD (all coordinates in the input dimension). * The vectors must be properly orthogonal: not coplanar or collinear. This is not checked! * @param scaling :: a vector of size outD of the scaling to perform in each of the * OUTPUT dimensions. * @throw if inconsistent vector sizes are received, or zero-length */ void CoordTransformAffine::buildOrthogonal(const Mantid::Kernel::VMD & origin, const std::vector< Mantid::Kernel::VMD> & axes, const Mantid::Kernel::VMD & scaling) { if (origin.size() != inD) throw std::runtime_error("CoordTransformAffine::buildOrthogonal(): the origin must be in the dimensions of the input workspace (length inD)."); if (axes.size() != outD) throw std::runtime_error("CoordTransformAffine::buildOrthogonal(): you must give as many basis vectors as there are dimensions in the output workspace."); if (scaling.size() != outD) throw std::runtime_error("CoordTransformAffine::buildOrthogonal(): the size of the scaling vector must be the same as the number of dimensions in the output workspace."); // Start with identity affineMatrix.identityMatrix(); for (size_t i=0; i<axes.size(); i++) { if (axes[i].length() == 0.0) throw std::runtime_error("CoordTransformAffine::buildOrthogonal(): one of the basis vector was of zero length."); if (axes[i].size() != inD) throw std::runtime_error("CoordTransformAffine::buildOrthogonal(): one of the basis vectors had the wrong number of dimensions (must be inD)."); // Normalize each axis to unity VMD basis = axes[i]; basis.normalize(); // The row of the affine matrix = the unit vector for (size_t j=0; j<basis.size(); j++) affineMatrix[i][j] = basis[j] * scaling[i]; // Now account for the translation coord_t transl = 0; for (size_t j=0; j<basis.size(); j++) transl += origin[j] * basis[j]; // dot product of origin * basis aka ( X0 . U ) // The last column of the matrix = the translation movement affineMatrix[i][inD] = -transl * scaling[i]; } // Copy into the raw matrix (for speed) copyRawMatrix(); }
bool PropertyCacheCreator::createMetaObject(int objectIndex, const QmlIR::Object *obj, QQmlPropertyCache *baseTypeCache) { QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(QQmlEnginePrivate::get(enginePrivate), obj->propertyCount(), obj->functionCount() + obj->propertyCount() + obj->signalCount(), obj->signalCount() + obj->propertyCount()); propertyCaches[objectIndex] = cache; struct TypeData { QV4::CompiledData::Property::Type dtype; int metaType; } builtinTypes[] = { { QV4::CompiledData::Property::Var, qMetaTypeId<QJSValue>() }, { QV4::CompiledData::Property::Variant, QMetaType::QVariant }, { QV4::CompiledData::Property::Int, QMetaType::Int }, { QV4::CompiledData::Property::Bool, QMetaType::Bool }, { QV4::CompiledData::Property::Real, QMetaType::Double }, { QV4::CompiledData::Property::String, QMetaType::QString }, { QV4::CompiledData::Property::Url, QMetaType::QUrl }, { QV4::CompiledData::Property::Color, QMetaType::QColor }, { QV4::CompiledData::Property::Font, QMetaType::QFont }, { QV4::CompiledData::Property::Time, QMetaType::QTime }, { QV4::CompiledData::Property::Date, QMetaType::QDate }, { QV4::CompiledData::Property::DateTime, QMetaType::QDateTime }, { QV4::CompiledData::Property::Rect, QMetaType::QRectF }, { QV4::CompiledData::Property::Point, QMetaType::QPointF }, { QV4::CompiledData::Property::Size, QMetaType::QSizeF }, { QV4::CompiledData::Property::Vector2D, QMetaType::QVector2D }, { QV4::CompiledData::Property::Vector3D, QMetaType::QVector3D }, { QV4::CompiledData::Property::Vector4D, QMetaType::QVector4D }, { QV4::CompiledData::Property::Matrix4x4, QMetaType::QMatrix4x4 }, { QV4::CompiledData::Property::Quaternion, QMetaType::QQuaternion } }; static const uint builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData); QByteArray newClassName; if (objectIndex == compiler->rootObjectIndex()) { QString path = compiler->data()->url.path(); int lastSlash = path.lastIndexOf(QLatin1Char('/')); if (lastSlash > -1) { QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5); if (!nameBase.isEmpty() && nameBase.at(0).isUpper()) newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1)); } } if (newClassName.isEmpty()) { newClassName = QQmlMetaObject(baseTypeCache).className(); newClassName.append("_QML_"); newClassName.append(QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1))); } cache->_dynamicClassName = newClassName; int aliasCount = 0; int varPropCount = 0; QmlIR::PropertyResolver resolver(baseTypeCache); for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) { if (p->type == QV4::CompiledData::Property::Alias) aliasCount++; else if (p->type == QV4::CompiledData::Property::Var) varPropCount++; // No point doing this for both the alias and non alias cases bool notInRevision = false; QQmlPropertyData *d = resolver.property(stringAt(p->nameIndex), ¬InRevision); if (d && d->isFinal()) { compiler->recordError(p->location, tr("Cannot override FINAL property")); return false; } } typedef QQmlVMEMetaData VMD; QByteArray &dynamicData = vmeMetaObjects[objectIndex] = QByteArray(sizeof(QQmlVMEMetaData) + obj->propertyCount() * sizeof(VMD::PropertyData) + obj->functionCount() * sizeof(VMD::MethodData) + aliasCount * sizeof(VMD::AliasData), 0); int effectivePropertyIndex = cache->propertyIndexCacheStart; int effectiveMethodIndex = cache->methodIndexCacheStart; // For property change signal override detection. // We prepopulate a set of signal names which already exist in the object, // and throw an error if there is a signal/method defined as an override. QSet<QString> seenSignals; seenSignals << QStringLiteral("destroyed") << QStringLiteral("parentChanged") << QStringLiteral("objectNameChanged"); QQmlPropertyCache *parentCache = cache; while ((parentCache = parentCache->parent())) { if (int pSigCount = parentCache->signalCount()) { int pSigOffset = parentCache->signalOffset(); for (int i = pSigOffset; i < pSigCount; ++i) { QQmlPropertyData *currPSig = parentCache->signal(i); // XXX TODO: find a better way to get signal name from the property data :-/ for (QQmlPropertyCache::StringCache::ConstIterator iter = parentCache->stringCache.begin(); iter != parentCache->stringCache.end(); ++iter) { if (currPSig == (*iter).second) { seenSignals.insert(iter.key()); break; } } } } } // First set up notify signals for properties - first normal, then var, then alias enum { NSS_Normal = 0, NSS_Var = 1, NSS_Alias = 2 }; for (int ii = NSS_Normal; ii <= NSS_Alias; ++ii) { // 0 == normal, 1 == var, 2 == alias if (ii == NSS_Var && varPropCount == 0) continue; else if (ii == NSS_Alias && aliasCount == 0) continue; for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) { if ((ii == NSS_Normal && (p->type == QV4::CompiledData::Property::Alias || p->type == QV4::CompiledData::Property::Var)) || ((ii == NSS_Var) && (p->type != QV4::CompiledData::Property::Var)) || ((ii == NSS_Alias) && (p->type != QV4::CompiledData::Property::Alias))) continue; quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMESignal; QString changedSigName = stringAt(p->nameIndex) + QLatin1String("Changed"); seenSignals.insert(changedSigName); cache->appendSignal(changedSigName, flags, effectiveMethodIndex++); } } // Dynamic signals for (const QmlIR::Signal *s = obj->firstSignal(); s; s = s->next) { const int paramCount = s->parameters->count; QList<QByteArray> names; QVarLengthArray<int, 10> paramTypes(paramCount?(paramCount + 1):0); if (paramCount) { paramTypes[0] = paramCount; QmlIR::SignalParameter *param = s->parameters->first; for (int i = 0; i < paramCount; ++i, param = param->next) { names.append(stringAt(param->nameIndex).toUtf8()); if (param->type < builtinTypeCount) { // built-in type paramTypes[i + 1] = builtinTypes[param->type].metaType; } else { // lazily resolved type Q_ASSERT(param->type == QV4::CompiledData::Property::Custom); const QString customTypeName = stringAt(param->customTypeNameIndex); QQmlType *qmltype = 0; if (!imports->resolveType(customTypeName, &qmltype, 0, 0, 0)) { compiler->recordError(s->location, tr("Invalid signal parameter type: %1").arg(customTypeName)); return false; } if (qmltype->isComposite()) { // Composite type usage qDebug() << "Composite type usage2" << qmltype->sourceUrl() << "Line" << param->location.line << "Col" << param->location.column; QmlCompilation::TypeReference *typeRef = compiler->findTypeRef(param->customTypeNameIndex); Q_ASSERT(typeRef->component->compiledData != NULL); paramTypes[i + 1] = typeRef->component->compiledData->metaTypeId; } else { paramTypes[i + 1] = qmltype->typeId(); } } } } ((QQmlVMEMetaData *)dynamicData.data())->signalCount++; quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMESignal; if (paramCount) flags |= QQmlPropertyData::HasArguments; QString signalName = stringAt(s->nameIndex); if (seenSignals.contains(signalName)) { compiler->recordError(s->location, tr("Duplicate signal name: invalid override of property change signal or superclass signal")); return false; } seenSignals.insert(signalName); cache->appendSignal(signalName, flags, effectiveMethodIndex++, paramCount?paramTypes.constData():0, names); } // Dynamic slots for (const QmlIR::Function *s = obj->firstFunction(); s; s = s->next) { QQmlJS::AST::FunctionDeclaration *astFunction = s->functionDeclaration; quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction; if (astFunction->formals) flags |= QQmlPropertyData::HasArguments; QString slotName = astFunction->name.toString(); if (seenSignals.contains(slotName)) { compiler->recordError(s->location, tr("Duplicate method name: invalid override of property change signal or superclass signal")); return false; } // Note: we don't append slotName to the seenSignals list, since we don't // protect against overriding change signals or methods with properties. QList<QByteArray> parameterNames; QQmlJS::AST::FormalParameterList *param = astFunction->formals; while (param) { parameterNames << param->name.toUtf8(); param = param->next; } cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames); } // Dynamic properties (except var and aliases) int effectiveSignalIndex = cache->signalHandlerIndexCacheStart; int propertyIdx = 0; for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) { if (p->type == QV4::CompiledData::Property::Alias || p->type == QV4::CompiledData::Property::Var) continue; int propertyType = 0; int vmePropertyType = 0; quint32 propertyFlags = 0; if (p->type < builtinTypeCount) { propertyType = builtinTypes[p->type].metaType; vmePropertyType = propertyType; if (p->type == QV4::CompiledData::Property::Variant) propertyFlags |= QQmlPropertyData::IsQVariant; } else { Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList || p->type == QV4::CompiledData::Property::Custom); QQmlType *qmltype = 0; if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0)) { compiler->recordError(p->location, tr("Invalid property type")); return false; } Q_ASSERT(qmltype); if (qmltype->isComposite()) { // Composite type usage QmlCompilation::TypeReference *typeRef = compiler->findTypeRef(p->customTypeNameIndex); Q_ASSERT(typeRef->component->compiledData != NULL); QQmlCompiledData *data = typeRef->component->compiledData; if (p->type == QV4::CompiledData::Property::Custom) { propertyType = data->metaTypeId; vmePropertyType = QMetaType::QObjectStar; } else { propertyType = data->listMetaTypeId; vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >(); } } else { if (p->type == QV4::CompiledData::Property::Custom) { propertyType = qmltype->typeId(); vmePropertyType = QMetaType::QObjectStar; } else { propertyType = qmltype->qListTypeId(); vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >(); } } if (p->type == QV4::CompiledData::Property::Custom) propertyFlags |= QQmlPropertyData::IsQObjectDerived; else propertyFlags |= QQmlPropertyData::IsQList; } if ((!p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList) propertyFlags |= QQmlPropertyData::IsWritable; QString propertyName = stringAt(p->nameIndex); if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, propertyType, effectiveSignalIndex); effectiveSignalIndex++; VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); (vmd->propertyData() + vmd->propertyCount)->propertyType = vmePropertyType; vmd->propertyCount++; } // Now do var properties propertyIdx = 0; for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) { if (p->type != QV4::CompiledData::Property::Var) continue; quint32 propertyFlags = QQmlPropertyData::IsVarProperty; if (!p->flags & QV4::CompiledData::Property::IsReadOnly) propertyFlags |= QQmlPropertyData::IsWritable; VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); (vmd->propertyData() + vmd->propertyCount)->propertyType = QMetaType::QVariant; vmd->propertyCount++; ((QQmlVMEMetaData *)dynamicData.data())->varPropertyCount++; QString propertyName = stringAt(p->nameIndex); if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, QMetaType::QVariant, effectiveSignalIndex); effectiveSignalIndex++; } // Alias property count. Actual data is setup in buildDynamicMetaAliases ((QQmlVMEMetaData *)dynamicData.data())->aliasCount = aliasCount; // Dynamic slot data - comes after the property data for (const QmlIR::Function *s = obj->firstFunction(); s; s = s->next) { QQmlJS::AST::FunctionDeclaration *astFunction = s->functionDeclaration; int formalsCount = 0; QQmlJS::AST::FormalParameterList *param = astFunction->formals; while (param) { formalsCount++; param = param->next; } VMD::MethodData methodData = { /* runtimeFunctionIndex*/ 0, // ### formalsCount, /* s->location.start.line */0 }; // ### VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); VMD::MethodData &md = *(vmd->methodData() + vmd->methodCount); vmd->methodCount++; md = methodData; } return true; }
/** Automatically choose which coordinate to use as the X axis, * if we selected it to be automatic */ void MantidQwtIMDWorkspaceData::choosePlotAxis() { if (m_plotAxis == MantidQwtIMDWorkspaceData::PlotAuto) { if (m_transform) { // Find the start and end points in the original workspace VMD originalStart = m_transform->applyVMD(m_start); VMD originalEnd = m_transform->applyVMD(m_end); VMD diff = originalEnd - originalStart; // Now we find the dimension with the biggest change double largest = -1e30; // Default to 0 m_currentPlotAxis = 0; IMDWorkspace_const_sptr originalWS = m_originalWorkspace.lock(); bool regularBinnedMDWorkspace = false; if(auto mdew = boost::dynamic_pointer_cast<const Mantid::API::IMDEventWorkspace>(m_workspace)) { Mantid::API::BoxController_const_sptr controller = mdew->getBoxController(); bool atLeastOneDimNotIntegrated = false; for(size_t i = 0; i < mdew->getNumDims(); ++i) { if( mdew->getDimension(i)->getNBins() == controller->getSplitInto(i)) { if(!mdew->getDimension(i)->getIsIntegrated()) { atLeastOneDimNotIntegrated = true; } } } regularBinnedMDWorkspace = atLeastOneDimNotIntegrated; } if(NULL != boost::dynamic_pointer_cast<const Mantid::API::IMDHistoWorkspace>(originalWS) || regularBinnedMDWorkspace) { for (size_t d=0; d<diff.getNumDims(); d++) { if (fabs(diff[d]) > largest || ( originalWS && originalWS->getDimension(m_currentPlotAxis)->getIsIntegrated() ) ) { //Skip over any integrated dimensions if( originalWS && !originalWS->getDimension(d)->getIsIntegrated() ) { largest = fabs(diff[d]); m_currentPlotAxis = int(d); } } } } else { for (size_t d=0; d<diff.getNumDims(); d++) { if (fabs(diff[d]) > largest) { largest = fabs(diff[d]); m_currentPlotAxis = int(d); } } } } else // Drop to distance if the transform does not exist m_currentPlotAxis = MantidQwtIMDWorkspaceData::PlotDistance; } else { // Pass-through the value. m_currentPlotAxis = m_plotAxis; } }
/** Obtain coordinates for a line plot through a MDWorkspace. * Cross the workspace from start to end points, recording the signal along the *lin at either bin boundaries, or halfway between bin boundaries (which is bin *centres if the line is dimension aligned). If recording halfway values then *omit points in masked bins. * * @param start :: coordinates of the start point of the line * @param end :: coordinates of the end point of the line * @param normalize :: how to normalize the signal * @returns :: LinePlot with x as the boundaries of the bins, relative * to start of the line, y set to the normalized signal for each bin with * Length = length(x) - 1 and e as the error vector for each bin. * @param bin_centres :: if true then record points halfway between bin *boundaries, otherwise record on bin boundaries */ IMDWorkspace::LinePlot MDHistoWorkspace::getLinePoints( const Mantid::Kernel::VMD &start, const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize, const bool bin_centres) const { LinePlot line; size_t nd = this->getNumDims(); if (start.getNumDims() != nd) throw std::runtime_error("Start point must have the same number of " "dimensions as the workspace."); if (end.getNumDims() != nd) throw std::runtime_error( "End point must have the same number of dimensions as the workspace."); // Unit-vector of the direction VMD dir = end - start; const auto length = dir.normalize(); // Vector with +1 where direction is positive, -1 where negative #define sgn(x) ((x < 0) ? -1.0f : ((x > 0.) ? 1.0f : 0.0f)) VMD dirSign(nd); for (size_t d = 0; d < nd; d++) { dirSign[d] = sgn(dir[d]); } const size_t BADINDEX = size_t(-1); // Dimensions of the workspace boost::scoped_array<size_t> index(new size_t[nd]); boost::scoped_array<size_t> numBins(new size_t[nd]); for (size_t d = 0; d < nd; d++) { IMDDimension_const_sptr dim = this->getDimension(d); index[d] = BADINDEX; numBins[d] = dim->getNBins(); } const std::set<coord_t> boundaries = getBinBoundariesOnLine(start, end, nd, dir, length); if (boundaries.empty()) { this->makeSinglePointWithNaN(line.x, line.y, line.e); // Require x.size() = y.size()+1 if recording bin boundaries if (!bin_centres) line.x.push_back(length); return line; } else { // Get the first point std::set<coord_t>::iterator it; it = boundaries.cbegin(); coord_t lastLinePos = *it; VMD lastPos = start + (dir * lastLinePos); if (!bin_centres) { line.x.push_back(lastLinePos); } ++it; coord_t linePos = 0; for (; it != boundaries.cend(); ++it) { // This is our current position along the line linePos = *it; // This is the full position at this boundary VMD pos = start + (dir * linePos); // Position in the middle of the bin VMD middle = (pos + lastPos) * 0.5; // Find the signal in this bin const auto linearIndex = this->getLinearIndexAtCoord(middle.getBareArray()); if (bin_centres && !this->getIsMaskedAt(linearIndex)) { coord_t bin_centrePos = static_cast<coord_t>((linePos + lastLinePos) * 0.5); line.x.push_back(bin_centrePos); } else if (!bin_centres) line.x.push_back(linePos); if (linearIndex < m_length) { auto normalizer = getNormalizationFactor(normalize, linearIndex); // And add the normalized signal/error to the list too auto signal = this->getSignalAt(linearIndex) * normalizer; if (boost::math::isinf(signal)) { // The plotting library (qwt) doesn't like infs. signal = std::numeric_limits<signal_t>::quiet_NaN(); } if (!bin_centres || !this->getIsMaskedAt(linearIndex)) { line.y.push_back(signal); line.e.push_back(this->getErrorAt(linearIndex) * normalizer); } // Save the position for next bin lastPos = pos; } else { // Invalid index. This shouldn't happen line.y.push_back(std::numeric_limits<signal_t>::quiet_NaN()); line.e.push_back(std::numeric_limits<signal_t>::quiet_NaN()); } lastLinePos = linePos; } // for each unique boundary // If all bins were masked if (line.x.size() == 0) { this->makeSinglePointWithNaN(line.x, line.y, line.e); } } return line; }
bool QmcTypeUnitComponentAndAliasResolver::addAliases() { // add aliases //QmcUnitAlias al = {0, 0, 0, 8, 0, 0, 24}; //qmcTypeUnit->unit->aliases.append(al); // see QQmlComponentAndAliasResolver::resolve int effectiveAliasIndex = -1; int effectivePropertyIndex = -1; int effectiveSignalIndex = -1; int currentObjectIndex = -1; QQmlPropertyCache *propertyCache = NULL; foreach (const QmcUnitAlias &alias, qmcTypeUnit->unit->aliases) { if ((int)alias.objectIndex != currentObjectIndex) { currentObjectIndex = alias.objectIndex; effectiveAliasIndex = 0; propertyCache = qmcTypeUnit->propertyCaches.at(alias.objectIndex); effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count(); effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count(); } Q_ASSERT(propertyCache); QQmlVMEMetaData::AliasData aliasData; aliasData.contextIdx = alias.contextIndex; aliasData.propertyIdx = alias.targetPropertyIndex; aliasData.propType = alias.propertyType; aliasData.flags = alias.flags; aliasData.notifySignal = alias.notifySignal; typedef QQmlVMEMetaData VMD; QByteArray &dynamicData = qmcTypeUnit->vmeMetaObjects[alias.objectIndex]; Q_ASSERT(!dynamicData.isEmpty()); VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); *(vmd->aliasData() + effectiveAliasIndex++) = aliasData; Q_ASSERT(dynamicData.isDetached()); // TBD: propertyCache const QV4::CompiledData::Object *obj = qmcTypeUnit->compiledData->qmlUnit->objectAt(alias.objectIndex); Q_ASSERT(obj); Q_ASSERT(alias.propertyIndex < obj->nProperties); const QV4::CompiledData::Property *p = &obj->propertyTable()[alias.propertyIndex]; Q_ASSERT(p); QString propertyName = qmcTypeUnit->stringAt(p->nameIndex); const QString aliasPropertyValue = qmcTypeUnit->stringAt(p->aliasPropertyValueIndex); //const int idIndex = p->aliasIdValueIndex; const int targetObjectIndex = alias.targetObjectIndex; #if 0 const int idIndex = p->aliasIdValueIndex; const int targetObjectIndex = _idToObjectIndex.value(idIndex, -1); if (targetObjectIndex == -1) { recordError(p->aliasLocation, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex))); return false; } #endif QStringRef property; QStringRef subProperty; const int propertySeparator = aliasPropertyValue.indexOf(QLatin1Char('.')); if (propertySeparator != -1) { property = aliasPropertyValue.leftRef(propertySeparator); subProperty = aliasPropertyValue.midRef(propertySeparator + 1); } else property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length()); quint32 propertyFlags = QQmlPropertyData::IsAlias; int type = 0; bool writable = false; bool resettable = false; if (property.isEmpty()) { const QV4::CompiledData::Object *targetObject = qmcTypeUnit->compiledData->qmlUnit->objectAt(targetObjectIndex); QQmlCompiledData::TypeReference *typeRef = qmcTypeUnit->compiledData->resolvedTypes.value(targetObject->inheritedTypeNameIndex); Q_ASSERT(typeRef); if (typeRef->type) type = typeRef->type->typeId(); else type = typeRef->component->metaTypeId; //flags |= QML_ALIAS_FLAG_PTR; propertyFlags |= QQmlPropertyData::IsQObjectDerived; } else { QQmlPropertyCache *targetCache = qmcTypeUnit->propertyCaches.at(targetObjectIndex); Q_ASSERT(targetCache); QmlIR::PropertyResolver resolver(targetCache); QQmlPropertyData *targetProperty = resolver.property(property.toString()); if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) { return false; } //propIdx = targetProperty->coreIndex; type = targetProperty->propType; writable = targetProperty->isWritable(); resettable = targetProperty->isResettable(); //notifySignal = targetProperty->notifyIndex; if (!subProperty.isEmpty()) { QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type); if (!valueType) { return false; } //propType = type; int valueTypeIndex = valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData()); if (valueTypeIndex == -1) { return false; } Q_ASSERT(valueTypeIndex <= 0x0000FFFF); //propIdx |= (valueTypeIndex << 16); if (valueType->metaObject()->property(valueTypeIndex).isEnumType()) type = QVariant::Int; else type = valueType->metaObject()->property(valueTypeIndex).userType(); } else { if (targetProperty->isEnum()) { type = QVariant::Int; } else { // Copy type flags propertyFlags |= targetProperty->getFlags() & QQmlPropertyData::PropTypeFlagMask; if (targetProperty->isVarProperty()) propertyFlags |= QQmlPropertyData::IsQVariant; #if 0 if (targetProperty->isQObject()) flags |= QML_ALIAS_FLAG_PTR; #endif } } } if (!(p->flags & QV4::CompiledData::Property::IsReadOnly) && writable) propertyFlags |= QQmlPropertyData::IsWritable; else propertyFlags &= ~QQmlPropertyData::IsWritable; if (resettable) propertyFlags |= QQmlPropertyData::IsResettable; else propertyFlags &= ~QQmlPropertyData::IsResettable; if ((int)alias.propertyIndex == obj->indexOfDefaultProperty) propertyCache->_defaultPropertyName = propertyName; propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, type, effectiveSignalIndex++); } return true; }
void MDPhi::dump(Region * rg, UseDefMgr * mgr) { ASSERT0(rg); ASSERT0(is_phi()); if (g_tfile == NULL) { return; } List<IRBB*> preds; IR_CFG * cfg = rg->getCFG(); ASSERT0(cfg); cfg->get_preds(preds, getBB()); IRBB * pred = preds.get_head(); ASSERT0(getResult()); fprintf(g_tfile, "Phi: MD%dV%d <- ", getResult()->mdid(), getResult()->version()); for (IR const* opnd = getOpndList(); opnd != NULL; opnd = opnd->get_next()) { if (opnd != getOpndList()) { fprintf(g_tfile, ", "); } switch (opnd->get_code()) { case IR_CONST: fprintf(g_tfile, "Const"); break; case IR_LDA: fprintf(g_tfile, "Lda"); break; case IR_ID: { VMD * vopnd = getOpndVMD(opnd, mgr); fprintf(g_tfile, "MD%dV%d(id:%d)", vopnd->mdid(), vopnd->version(), opnd->id()); } break; default: UNREACH(); } ASSERT0(pred); fprintf(g_tfile, "(BB%d)", pred->id()); pred = preds.get_next(); } VMD * res = getResult(); ASSERT0(res); fprintf(g_tfile, "|UsedBy:"); SEGIter * vit = NULL; bool first = true; for (INT i2 = res->getOccSet()->get_first(&vit); i2 >= 0; i2 = res->getOccSet()->get_next(i2, &vit)) { if (first) { first = false; } else { fprintf(g_tfile, ","); } IR const* use = rg->getIR(i2); ASSERT0(use && (use->isMemoryRef() || use->is_id())); fprintf(g_tfile, "%s(id:%d)", IRNAME(use), use->id()); } fflush(g_tfile); }