void StraightRodPair::buildModules(Container& modules, const RodTemplate& rodTemplate, const vector<double>& posList, BuildDir direction, int parity, int side) { for (int i=0; i<(int)posList.size(); i++, parity = -parity) { BarrelModule* mod = GeometryFactory::make<BarrelModule>(i < rodTemplate.size() ? *rodTemplate[i].get() : *rodTemplate.rbegin()->get()); mod->myid(i+1); mod->side(side); //mod->store(propertyTree()); //if (ringNode.count(i+1) > 0) mod->store(ringNode.at(i+1)); //mod->build(); mod->translateR(parity > 0 ? smallDelta() : -smallDelta()); mod->flipped(parity != 1); // Attaching the correct flipped() value to the module mod->translateZ(posList[i] + (direction == BuildDir::RIGHT ? mod->length()/2 : -mod->length()/2)); // mod->translate(XYZVector(parity > 0 ? smallDelta() : -smallDelta(), 0, posList[i])); // CUIDADO: we are now translating the center instead of an edge as before modules.push_back(mod); } }
std::pair<float, int> Layer::calculateOptimalLayerParms(const RodTemplate& rodTemplate) { // CUIDADO fix placeRadiusHint!!!!! double maxDsDistance = (*std::max_element(rodTemplate.begin(), rodTemplate.end(), [](const unique_ptr<BarrelModule>& m1, const unique_ptr<BarrelModule>& m2) { return m1->dsDistance() > m2->dsDistance(); } ))->dsDistance(); float moduleWidth = (*rodTemplate.rbegin())->minWidth(); float f = moduleWidth/2 - phiOverlap()/2; float gamma = atan(f/(placeRadiusHint() + bigDelta() + smallDelta() + maxDsDistance/2)) + atan(f/(placeRadiusHint() - bigDelta() + smallDelta() + maxDsDistance/2)); float tentativeModsPerSegment = 2*M_PI/(gamma * phiSegments()); float optimalRadius; int optimalModsPerSegment; switch (radiusMode()) { case SHRINK: optimalModsPerSegment = floor(tentativeModsPerSegment); optimalRadius = calculatePlaceRadius(optimalModsPerSegment*phiSegments(), bigDelta(), smallDelta(), maxDsDistance, moduleWidth, phiOverlap()); break; case ENLARGE: optimalModsPerSegment = ceil(tentativeModsPerSegment); optimalRadius = calculatePlaceRadius(optimalModsPerSegment*phiSegments(), bigDelta(), smallDelta(), maxDsDistance, moduleWidth, phiOverlap()); break; case FIXED: optimalModsPerSegment = ceil(tentativeModsPerSegment); optimalRadius = placeRadiusHint(); break; case AUTO: { int modsPerSegLo = floor(tentativeModsPerSegment); int modsPerSegHi = ceil(tentativeModsPerSegment); float radiusLo = calculatePlaceRadius(modsPerSegLo*phiSegments(), bigDelta(), smallDelta(), maxDsDistance, moduleWidth, phiOverlap()); float radiusHi = calculatePlaceRadius(modsPerSegHi*phiSegments(), bigDelta(), smallDelta(), maxDsDistance, moduleWidth, phiOverlap()); if (fabs(radiusHi - placeRadiusHint()) < fabs(radiusLo - placeRadiusHint())) { optimalRadius = radiusHi; optimalModsPerSegment = modsPerSegHi; } else { optimalRadius = radiusLo; optimalModsPerSegment = modsPerSegLo; } break; } default: throw PathfulException("Invalid value for enum radiusMode"); } return std::make_pair(optimalRadius, optimalModsPerSegment*phiSegments()); }
void addNumpyToPolygonF(QPolygonF& poly, const Tuple2Ptrs& d) { // iterate over rows until none left const int numcols = d.data.size(); QPointF lastpt(-1e6, -1e6); for(int row=0 ; ; ++row) { bool ifany = false; // the numcols-1 makes sure we don't get odd numbers of columns for(int col=0; col < (numcols-1); col += 2) { // add point if point in two columns if( row < d.dims[col] && row < d.dims[col+1] ) { const QPointF pt(d.data[col][row], d.data[col+1][row]); if( ! smallDelta(pt, lastpt) ) { poly << pt; lastpt = pt; } ifany = true; } } // exit loop if no more columns if(! ifany ) break; } }
void Ring::buildTopDown() { double startRadius = buildStartRadius()-ringGap(); if (ringInnerRadius()>0){ logWARNING("inner radius was set for a top-down endcap building. Ignoring ringInnerRadius."); } if (ringOuterRadius()>0) { if (ringGap()!=0) logWARNING("outerRadius and ringGap were both specified. Ignoring ringGap."); startRadius = ringOuterRadius(); } buildStartRadius(startRadius); RectangularModule* rmod = GeometryFactory::make<RectangularModule>(); rmod->store(propertyTree()); auto optimalRingParms = computeOptimalRingParametersRectangle(rmod->width(), buildStartRadius()); int numMods = optimalRingParms.second; EndcapModule* emod = GeometryFactory::make<EndcapModule>(rmod); emod->store(propertyTree()); emod->build(); emod->translate(XYZVector(buildStartRadius() - rmod->length()/2, 0, 0)); minRadius_ = buildStartRadius() - rmod->length(); maxRadius_ = buildStartRadius(); if (numModules.state()) numMods = numModules(); else numModules(numMods); buildModules(emod, numMods, smallDelta()); delete emod; }
void plotPathsToPainter(QPainter& painter, QPainterPath& path, const Numpy1DObj& x, const Numpy1DObj& y, const Numpy1DObj* scaling, const QRectF* clip, const QImage* colorimg) { QRectF cliprect( QPointF(-32767,-32767), QPointF(32767,32767) ); if( clip != 0 ) { qreal x1, y1, x2, y2; clip->getCoords(&x1, &y1, &x2, &y2); cliprect.setCoords(x1, y1, x2, y2); } QRectF pathbox = path.boundingRect(); cliprect.adjust(pathbox.left(), pathbox.top(), pathbox.bottom(), pathbox.right()); // keep track of duplicate points QPointF lastpt(-1e6, -1e6); // keep original transformation for restoration after each iteration QTransform origtrans(painter.worldTransform()); // number of iterations int size = min(x.dim, y.dim); // if few color points, trim down number of paths if( colorimg != 0 ) size = min(size, colorimg->width()); // too few scaling points if( scaling != 0 ) size = min(size, scaling->dim); // draw each path for(int i = 0; i < size; ++i) { const QPointF pt(x(i), y(i)); if( cliprect.contains(pt) && ! smallDelta(lastpt, pt) ) { painter.translate(pt); if( scaling != 0 ) { // scale point if requested const qreal s = (*scaling)(i); painter.scale(s, s); } if( colorimg != 0 ) { // get color from pixel and create a new brush QBrush b( QColor::fromRgba(colorimg->pixel(i, 0)) ); painter.setBrush(b); } painter.drawPath(path); painter.setWorldTransform(origtrans); lastpt = pt; } } }
double StraightRodPair::computeNextZ(double newDsLength, double newDsDistance, double lastDsDistance, double lastZ, BuildDir direction, int parity) { double d = smallDelta(); double dz = zError(); double ov = zOverlap(); double maxr = maxBuildRadius(); double minr = minBuildRadius(); double newR = (parity > 0 ? maxr + d : minr - d) - newDsDistance/2; double lastR = (parity > 0 ? maxr - d : minr + d) + lastDsDistance/2; double newZ = lastZ; if (!beamSpotCover()) dz = 0; if (direction == BuildDir::RIGHT) { double originZ = parity > 0 ? dz : -dz; double newZorigin = (newZ - ov) * newR/lastR; double newZshifted = (newZ - originZ) * newR/lastR + originZ; if (beamSpotCover()) newZ = MIN(newZorigin, newZshifted); else newZ = newZorigin; if (forbiddenRange.state()) { double forbiddenRange_begin,forbiddenRange_end; forbiddenRange_begin=(forbiddenRange[0]+forbiddenRange[1])/2; forbiddenRange_end=forbiddenRange[1]; if (newZ-lastZ >= (forbiddenRange_begin - newDsLength) && newZ - lastZ <= (forbiddenRange_end - newDsLength)) { newZ = lastZ + forbiddenRange_begin - newDsLength; } else { forbiddenRange_begin=forbiddenRange[0]; forbiddenRange_end=(forbiddenRange[0]+forbiddenRange[1])/2; if (newZ-lastZ >= (forbiddenRange_begin - newDsLength) && newZ - lastZ <= (forbiddenRange_end - newDsLength)) { newZ = lastZ + forbiddenRange_begin - newDsLength; } } } } else { double originZ = parity > 0 ? -dz : dz; double newZorigin = (newZ + ov) * newR/lastR; double newZshifted = (newZ - originZ) * newR/lastR + originZ; if (beamSpotCover()) newZ = MAX(newZorigin, newZshifted); else newZ = newZorigin; if (forbiddenRange.state()) { double forbiddenRange_begin,forbiddenRange_end; forbiddenRange_begin=(forbiddenRange[0]+forbiddenRange[1])/2; forbiddenRange_end=forbiddenRange[1]; if (lastZ - newZ >= (forbiddenRange_begin - newDsLength) && lastZ - newZ <= (forbiddenRange_end - newDsLength)){ newZ = lastZ - forbiddenRange_begin + newDsLength; } else { forbiddenRange_begin=forbiddenRange[0]; forbiddenRange_end=(forbiddenRange[0]+forbiddenRange[1])/2; if (lastZ - newZ >= (forbiddenRange_begin - newDsLength) && lastZ - newZ <= (forbiddenRange_end - newDsLength)){ newZ = lastZ - forbiddenRange_begin + newDsLength; } } } } return newZ; }
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); } }
void Ring::buildBottomUp() { double startRadius = buildStartRadius()+ringGap(); if (ringOuterRadius()>0){ logWARNING("outer radius was set for a bottom-up endcap building. Ignoring ringOuterRadius."); } if (ringInnerRadius()>0) { if (ringGap()!=0) logWARNING("innerRadius and ringGap were both specified. Ignoring ringGap."); startRadius = ringInnerRadius(); } buildStartRadius(startRadius); int numMods; double modLength; EndcapModule* emod = nullptr; if (moduleShape() == ModuleShape::WEDGE) { WedgeModule* wmod = GeometryFactory::make<WedgeModule>(); wmod->store(propertyTree()); auto optimalRingParms = computeOptimalRingParametersWedge(wmod->waferDiameter(), buildStartRadius()); double alpha = optimalRingParms.first; numMods = optimalRingParms.second; wmod->buildAperture(alpha); wmod->buildDistance(buildStartRadius()); wmod->buildCropDistance(buildCropRadius()); wmod->build(); modLength = wmod->length(); emod = GeometryFactory::make<EndcapModule>(wmod); } else { RectangularModule* rmod = GeometryFactory::make<RectangularModule>(); rmod->store(propertyTree()); rmod->build(); auto optimalRingParms = computeOptimalRingParametersRectangle(rmod->width(), buildStartRadius() + rmod->length()); numMods = optimalRingParms.second; modLength = rmod->length(); emod = GeometryFactory::make<EndcapModule>(rmod); } emod->store(propertyTree()); emod->build(); emod->translate(XYZVector(buildStartRadius() + modLength/2, 0, 0)); minRadius_ = buildStartRadius(); maxRadius_ = buildStartRadius() + modLength; if (numModules.state()) numMods = numModules(); else numModules(numMods); buildModules(emod, numMods, smallDelta()); delete emod; }