std::pair<double, double> DetectorModule::minMaxEtaWithError(double zError) const { if (cachedZError_ != zError) { cachedZError_ = zError; double eta1 = (XYZVector(0., maxR(), maxZ() + zError)).Eta(); double eta2 = (XYZVector(0., minR(), minZ() - zError)).Eta(); double eta3 = (XYZVector(0., minR(), maxZ() + zError)).Eta(); double eta4 = (XYZVector(0., maxR(), minZ() - zError)).Eta(); cachedMinMaxEtaWithError_ = std::minmax({eta1, eta2, eta3, eta4}); //cachedMinMaxEtaWithError_ = std::make_pair(MIN(eta1, eta2), MAX(eta1, eta2)); } return cachedMinMaxEtaWithError_; }
// True if this structure has valid values bool isValid() { return minX() <= maxX() && minY() <= maxY() && minZ() <= maxZ(); }
bool Boundary::isValid() const { bool valid = std::isfinite (minX ()) && std::isfinite (maxX ()) && std::isfinite (minY ()) && std::isfinite (maxY ()) && std::isfinite (minZ ()) && std::isfinite (maxZ ()); return valid; }
void StraightRodPair::buildFull(const RodTemplate& rodTemplate) { double startZ = startZMode() == StartZMode::MODULECENTER ? -(*rodTemplate.begin())->length()/2. : 0.; auto zListPair = computeZListPair(rodTemplate.begin(), rodTemplate.end(), startZ, 0); // actual module creation // CUIDADO log rod balancing effort buildModules(zPlusModules_, rodTemplate, zListPair.first, BuildDir::RIGHT, zPlusParity(), 1); double currMaxZ = zPlusModules_.size() > 1 ? MAX(zPlusModules_.rbegin()->planarMaxZ(), (zPlusModules_.rbegin()+1)->planarMaxZ()) : (!zPlusModules_.empty() ? zPlusModules_.rbegin()->planarMaxZ() : 0.); // CUIDADO this only checks the positive side... the negative side might actually have a higher fabs(maxZ) if the barrel is long enough and there's an inversion buildModules(zMinusModules_, rodTemplate, zListPair.second, BuildDir::LEFT, -zPlusParity(), -1); auto collisionsZPlus = solveCollisionsZPlus(); auto collisionsZMinus = solveCollisionsZMinus(); if (!collisionsZPlus.empty() || !collisionsZMinus.empty()) logWARNING("Some modules have been translated to avoid collisions. Check info tab"); if (compressed() && maxZ.state() && currMaxZ > maxZ()) compressToZ(maxZ()); currMaxZ = zPlusModules_.size() > 1 ? MAX(zPlusModules_.rbegin()->planarMaxZ(), (zPlusModules_.rbegin()+1)->planarMaxZ()) : (!zPlusModules_.empty() ? zPlusModules_.rbegin()->planarMaxZ() : 0.); maxZ(currMaxZ); }
void StraightRodPair::buildMezzanine(const RodTemplate& rodTemplate) { // compute Z list (only once since the second mezzanine has just inverted signs for z) vector<double> zList = computeZList(rodTemplate.rbegin(), rodTemplate.rend(), startZ(), BuildDir::LEFT, zPlusParity(), false); vector<double> zListNeg; std::transform(zList.begin(), zList.end(), std::back_inserter(zListNeg), std::negate<double>()); buildModules(zPlusModules_, rodTemplate, zList, BuildDir::LEFT, zPlusParity(), 1); // CUIDADO mezzanine layer rings in reverse order???? maxZ(startZ()); buildModules(zMinusModules_, rodTemplate, zListNeg, BuildDir::RIGHT, zPlusParity(), -1); }
template<typename Iterator> vector<double> StraightRodPair::computeZList(Iterator begin, Iterator end, double startZ, BuildDir direction, int smallParity, bool fixedStartZ) { vector<double> zList; double targetZ = maxZ.state() ? maxZ() : std::numeric_limits<double>::max(); // unreachable target in case maxZ not set int targetMods = buildNumModules.state() ? buildNumModules() : std::numeric_limits<int>::max(); // unreachable target in case numModules not set // If we rely on numModules and we start from the center, then the number of modules on the left side of the rod must be lower if ((startZMode() == StartZMode::MODULECENTER) && (direction == BuildDir::LEFT)) targetMods--; double newZ = startZ; // + lengthOffset/2; int parity = smallParity; BarrelModule* lastm = begin->get(); int n = 0; if (fixedStartZ) { zList.push_back(newZ); newZ += (direction == BuildDir::RIGHT ? (*begin)->length() : (*begin)->length()); parity = -parity; ++begin; n = 1; } for (auto& curm : pair2range(make_pair(begin, end))) { if (abs(newZ) >= targetZ || n++ >= targetMods) break; newZ = computeNextZ(curm->length(), curm->dsDistance(), lastm->dsDistance(), newZ, direction, parity); zList.push_back(newZ); newZ += (direction == BuildDir::RIGHT ? curm->length() : -curm->length()); lastm = curm.get(); parity = -parity; } double lengthOffset = lastm->length(); double physicalLengthOffset = lastm->physicalLength(); for (; abs(newZ) < targetZ && n < targetMods; n++) { // in case the rodtemplate vector is finished but we haven't hit the targetZ or targetMods yet, we keep on using the last module for dsDistance and length newZ = computeNextZ(lastm->length(), lastm->dsDistance(), lastm->dsDistance(), newZ, direction, parity); zList.push_back(newZ); newZ += (direction == BuildDir::RIGHT ? lastm->length() : -lastm->length()); parity = -parity; } return zList; }
void Boundary::refer(const Boundary &boundary) { if (boundary.minX () < minX ()) setMinX (boundary.minX ()); if (boundary.maxX () > maxX ()) setMaxX (boundary.maxX ()); if (boundary.minY () < minY ()) setMinY (boundary.minY ()); if (boundary.maxY () > maxY ()) setMaxY (boundary.maxY ()); if (boundary.minZ () < minZ ()) setMinZ (boundary.minZ ()); if (boundary.maxZ () > maxZ ()) setMaxZ (boundary.maxZ ()); }
void Boundary::refer(const xjPoint &point) { if (point.x () < minX ()) setMinX (point.x ()); if (point.x () > maxX ()) setMaxX (point.x ()); if (point.y () < minY ()) setMinY (point.y ()); if (point.y () > maxY ()) setMaxY (point.y ()); if (point.z () < minZ ()) setMinZ (point.z ()); if (point.z () > maxZ ()) setMaxZ (point.z ()); }
void Layer::buildStraight() { RodTemplate rodTemplate = makeRodTemplate(); std::pair<double, int> optimalLayerParms = calculateOptimalLayerParms(rodTemplate); placeRadius_ = optimalLayerParms.first; numRods_ = optimalLayerParms.second; if (!minBuildRadius.state() || !maxBuildRadius.state()) { minBuildRadius(placeRadius_); maxBuildRadius(placeRadius_); } float rodPhiRotation = 2*M_PI/numRods_; StraightRodPair* first = GeometryFactory::make<StraightRodPair>(); first->myid(1); first->minBuildRadius(minBuildRadius()-bigDelta()); first->maxBuildRadius(maxBuildRadius()+bigDelta()); if (buildNumModules() > 0) first->buildNumModules(buildNumModules()); else if (maxZ.state()) first->maxZ(maxZ()); first->smallDelta(smallDelta()); //first->ringNode = ringNode; // we need to pass on the contents of the ringNode to allow the RodPair to build the module decorators first->store(propertyTree()); first->build(rodTemplate); logINFO(Form("Copying rod %s", fullid(*this).c_str())); StraightRodPair* second = GeometryFactory::clone(*first); second->myid(2); if (!sameParityRods()) second->zPlusParity(first->zPlusParity()*-1); first->translateR(placeRadius_ + (bigParity() > 0 ? bigDelta() : -bigDelta())); //first->translate(XYZVector(placeRadius_+bigDelta(), 0, 0)); rods_.push_back(first); second->translateR(placeRadius_ + (bigParity() > 0 ? -bigDelta() : bigDelta())); //second->translate(XYZVector(placeRadius_-bigDelta(), 0, 0)); second->rotateZ(rodPhiRotation); rods_.push_back(second); for (int i = 2; i < numRods_; i++) { RodPair* rod = i%2 ? GeometryFactory::clone(*second) : GeometryFactory::clone(*first); // clone rods rod->myid(i+1); rod->rotateZ(rodPhiRotation*(i%2 ? i-1 : i)); rods_.push_back(rod); } }
std::vector<double> PMFFilter::morphOpen(PointViewPtr view, float radius) { point_count_t np(view->size()); KD2Index index(*view); index.build(); std::vector<double> minZ(np), maxZ(np); typedef std::vector<PointId> PointIdVec; std::map<PointId, PointIdVec> neighborMap; // erode for (PointId i = 0; i < np; ++i) { double x = view->getFieldAs<double>(Dimension::Id::X, i); double y = view->getFieldAs<double>(Dimension::Id::Y, i); auto ids = index.radius(x, y, radius); // neighborMap.insert(std::pair<PointId, std::vector<PointId>(i, ids)); neighborMap[i] = ids; double localMin(std::numeric_limits<double>::max()); for (auto const& j : ids) { double z = view->getFieldAs<double>(Dimension::Id::Z, j); if (z < localMin) localMin = z; } minZ[i] = localMin; } // dilate for (PointId i = 0; i < np; ++i) { auto ids = neighborMap[i]; double localMax(std::numeric_limits<double>::lowest()); for (auto const& j : ids) { double z = minZ[j]; if (z > localMax) localMax = z; } maxZ[i] = localMax; } return maxZ; }
/*! Compute the point of the line with a given Z component \param theZLevel Z component to use in point computation \return Point on the line with Z component equal to theZLevel, if theZLevel is less then minim Z of the line return a point with -DBL_MAX in its components, if it is greater then maximum Z return a point with DBL_MAX in its components If the line is not valid return an invalid point If the line is horizontal with Z component equal to theZLevel return the begin point of the line */ GM_3dPoint GM_3dLine::pointAtZ(double theZLevel) const { if (!isValid()) { return GM_3dPoint(); } if (theZLevel < minZ() - GM_DIFF_TOLERANCE) { return GM_3dPoint(-DBL_MAX, -DBL_MAX, -DBL_MAX); } if (theZLevel > maxZ() + GM_DIFF_TOLERANCE) { return GM_3dPoint(DBL_MAX, DBL_MAX, DBL_MAX); } if (dz() < GM_NULL_TOLERANCE && fabs(theZLevel - mBegin.z()) < GM_DIFF_TOLERANCE) { return mBegin; } else { double ratio = fabs(theZLevel - begin().z()) / fabs(dz()); return GM_3dPoint(begin().x() + dx()*ratio, begin().y() + dy()*ratio, theZLevel); } }
void InteriorPointsConstructor::ForceDirectedAlgorithm2() { //Clone the data structure, and initialize it to 0; int n = _contourArray->length()/2; computeNumberVertices(); _interiorDisplacementArray = new AcArray<AcGePoint3d>[n+1]; int i,j, vIter; //int i,j,vIter; AcGePoint3d delta; //int vIter; double Volume = (maxX() - minX())*(maxY() - minY())*(maxZ() - minZ()); double surface = (maxX() - minX())*(maxY() - minY()); double kappa; if (Volume) kappa = sqrt(Volume/_numVertices); else kappa = sqrt(surface/_numVertices); setKappa(kappa); //acutPrintf(_T("Proceeding...\n")); vector<pair<int, int>> v; vector<pair<int, int>>::iterator it; for (vIter = 0; vIter<2; vIter++) { //Calculate repulsive forces for (i = 0; i < _contourArray->length()/2+1; i++) { for (j = 0; j < _interiorArray[i].length(); j++) { if (vIter == 0) { AcGePoint3d * newPoint = new AcGePoint3d; newPoint->x = 0.0; newPoint->y = 0.0; newPoint->z = 0.0; _interiorDisplacementArray[i].append(*newPoint); } else { _interiorDisplacementArray[i][j].x = 0.0; _interiorDisplacementArray[i][j].y = 0.0; _interiorDisplacementArray[i][j].z = 0.0; } } } //acutPrintf(_T("Proceeding...attractive ...\n")); //Calculate attractive forces; for (i = 0; i < _contourArray->length()/2; i++) { for (j = 0; j < _interiorArray[i].length(); j++) { if ((i != 0) && (j!=_interiorArray[i].length() - 1) && (j!=0) && (i!=_contourArray->length()/2)) { arrayNeighbour(v, i, j); for (it = v.begin(); it!=v.end(); it++) { delta.x = _interiorArray[(*it).first][(*it).second].x - _interiorArray[i][j].x; delta.y = _interiorArray[(*it).first][(*it).second].y - _interiorArray[i][j].y; delta.z = _interiorArray[(*it).first][(*it).second].z - _interiorArray[i][j].z; _interiorDisplacementArray[i][j].x = _interiorDisplacementArray[i][j].x + F_attractive(delta.x); _interiorDisplacementArray[i][j].y = _interiorDisplacementArray[i][j].y + F_attractive(delta.y); _interiorDisplacementArray[i][j].z = _interiorDisplacementArray[i][j].z + F_attractive(delta.z); } } } } //Limit the fluctuations first step: for (i = 0; i < _contourArray->length()/2+1; i++) { for (j = 0; j < _interiorArray[i].length(); j++) { _interiorArray[i][j].x = _interiorArray[i][j].x + _interiorDisplacementArray[i][j].x; _interiorArray[i][j].y = _interiorArray[i][j].y + _interiorDisplacementArray[i][j].y; _interiorArray[i][j].z = _interiorArray[i][j].z + _interiorDisplacementArray[i][j].z; } } } acutPrintf(_T("\nVolume: %f, numPoints: %d, kappa: %f\n"), Volume, _numVertices, _kappa); }
// Multi-objective genetic algorithm long int runMOGA(std::vector<Box*> &vectorBox, Data &data, std::list<Solution> & allSolution) { std::vector<Box*>::iterator itVector; FILE * pipe_fp = 0; // Gnuplot pipe int object_id = 0; // OPEN GNUPLOT (interactive mode) if (Argument::interactive) { if ( ( pipe_fp = popen("gnuplot", "w") ) != 0 ) { int num_obj = (*vectorBox.begin())->getNbObjective(); std::vector<double> minZ( num_obj, std::numeric_limits<double>::infinity() ), maxZ( num_obj, -std::numeric_limits<double>::infinity() ); for (itVector = vectorBox.begin(); itVector != vectorBox.end(); ++itVector) { for ( int k = 0; k < (*(*itVector)).getNbObjective(); ++k ) { minZ[k] = std::min( (*(*itVector)).getMinZ( k ), minZ[k] ); maxZ[k] = std::max( (*(*itVector)).getMaxZ( k ), maxZ[k] ); } } fputs( "set nokey\n", pipe_fp ); fputs( "set xlabel \"$z_1$\"\n", pipe_fp ); fputs( "set ylabel \"$z_2$\"\n", pipe_fp ); fprintf( pipe_fp, "set xrange [%f:%f]\n", minZ[0], maxZ[0] ); fprintf( pipe_fp, "set yrange [%f:%f]\n", minZ[1], maxZ[1] ); } else { std::cerr << "Error: gnuplot pipe failed" << std::endl; } } // Apply MOGA on each box for (itVector = vectorBox.begin(); itVector != vectorBox.end(); ++itVector) { // Draw the box associated if ( pipe_fp ) { ++object_id; fprintf( pipe_fp, "set object %d rectangle from %f,%f to %f,%f fillstyle empty\n", object_id, (*(*itVector)).getMinZ(0), (*(*itVector)).getMinZ(1), (*(*itVector)).getMaxZ(0), (*(*itVector)).getMaxZ(1) ); } MOGA m(*(*itVector), Argument::num_individuals, Argument::num_generations, Argument::Pc, Argument::Pm); m.pipe_fp_ = pipe_fp; m.compute(); allSolution.merge(m.solutions_); } // CLOSE GNUPLOT if ( pipe_fp ) { pclose(pipe_fp); } // FILTERING DOMINATED SOLUTIONS for ( std::list<Solution>::iterator it1 = allSolution.begin(); it1 != allSolution.end(); ++it1 ) { for ( std::list<Solution>::iterator it2 = it1; it2 != allSolution.end(); ++it2 ) { bool dominates = true, dominated = true; for (int k = 0; k < (*it1).getNbObjective() && (dominates || dominated); ++k) { if ( !( (*it1).getObj( k ) < (*it2).getObj( k ) ) ) dominates = false; if ( !( (*it2).getObj( k ) < (*it1).getObj( k ) ) ) dominated = false; } if ( dominates ) { it2 = allSolution.erase( it2 ); --it2; } if ( dominated ) { it1 = allSolution.erase( it1 ); --it1; break; } } } if (Argument::mode_export) { ToFile::saveYN(allSolution, data); } return (long int) allSolution.size(); }