void ConversionStation::build() { try { stationType_ = typeString.at(type_()); buildConversions(); } catch (const std::out_of_range& ex) { logERROR("Station type \"" + type_() + "\" not recognized."); } cleanup(); }
void Layer::buildTilted() { std::ifstream ifs(tiltedLayerSpecFile()); if (ifs.fail()) throw PathfulException("Cannot open tilted modules spec file \"" + tiltedLayerSpecFile() + "\""); string line; vector<TiltedModuleSpecs> tmspecs1, tmspecs2; while(getline(ifs, line).good()) { if (line.empty()) continue; auto tokens = split<double>(line, " ", false); if (tokens.size() < 7) { logERROR("Failed parsing tilted barrel line: " + line); continue; }; TiltedModuleSpecs t1{ tokens[0], tokens[1], tokens[2]*M_PI/180. }; TiltedModuleSpecs t2{ tokens[3], tokens[4], tokens[5]*M_PI/180. }; if (t1.valid()) tmspecs1.push_back(t1); if (t2.valid()) tmspecs2.push_back(t2); numRods_ = tokens[6]; // this assumes every row of the spec file has the same value for the last column (num rods in phi) } ifs.close(); buildNumModules(tmspecs1.size()); RodTemplate rodTemplate = makeRodTemplate(); float rodPhiRotation = 2*M_PI/numRods_; TiltedRodPair* first = GeometryFactory::make<TiltedRodPair>(); first->myid(1); first->store(propertyTree()); first->build(rodTemplate, tmspecs1, 1); rods_.push_back(first); TiltedRodPair* second = GeometryFactory::make<TiltedRodPair>(); second->myid(2); second->store(propertyTree()); second->build(rodTemplate, tmspecs2, 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); } // computing the layer's place radius as the average of all the modules' radii placeRadius_ = std::accumulate(tmspecs1.begin(), tmspecs1.end(), 0., [](double x, const TiltedModuleSpecs& t) { return x+t.r; }); placeRadius_ += std::accumulate(tmspecs2.begin(), tmspecs2.end(), 0., [](double x, const TiltedModuleSpecs& t) { return x+t.r; }); placeRadius_ /= tmspecs1.size() + tmspecs2.size(); }
void setup_sig_handlers(void) { struct sigaction sa; sa.sa_handler=sig_handler; sigemptyset(&sa.sa_mask); sa.sa_flags=SA_RESTART; if (sigaction(SIGTERM, &sa, NULL)) { logERROR("Failed to install SIGTERM handler"); } if (sigaction(SIGINT, &sa, NULL)) { logERROR("Failed to install SIGINT handler"); } if (sigaction(SIGUSR2, &sa, NULL)) { logERROR("Failed to install SIGUSR2 handler"); } if (sigaction(SIGPIPE, &sa, NULL)) { logERROR("Failed to install SIGPIPE handler"); } }
double MaterialObject::Element::scalingMultiplier() const { int sensorIndex = scaleOnSensor(); if(sensorIndex != 0) { if(materialType_ == MODULE) { try { return sensorChannels_.at(sensorIndex) / referenceSensors_.at(sensorIndex)->numChannels(); } catch (std::out_of_range& e) { std::stringstream error; error << "Sensor " << sensorIndex << " don't exists." << std::endl; logERROR(error.str()); } } else { logUniqueERROR("Is not possible to define scaling for materials not in module."); } } return 1.; }
void MaterialObject::Element::deployMaterialTo(MaterialObject& outputObject, const std::vector<std::string>& unitsToDeploy, bool onlyServices /*= false*/, double gramsMultiplier /*= 1.*/) const { const Element* elementToDeploy = this; bool valid = false; if ((! onlyServices) || (onlyServices && (service() == true))) { if((unit().compare("g") == 0) && (service() == true)) { logERROR(err_service1 + elementName() + err_service2); } else { valid = true; } // if (materialType_ == STATION) { // if(unit().compare("g") == 0) { // logERROR(err_service1 + elementName() + err_service2); // } else { // valid = true; // } // } else if (materialType_ == ROD) { // if((unit().compare("g") == 0) && (service() == true) { // logERROR(err_service1 + elementName() + err_service2); // } else { // valid = true; // } // } else if (materialType_ == MODULE) { // if (service() == true) { // valid = true; // } // } if(valid) { for(const std::string& unitToDeploy : unitsToDeploy) { if (unit().compare(unitToDeploy) == 0) { if (((materialType_ == ROD) || (materialType_ == MODULE)) && (service()==true) && (unit().compare("mm") == 0)) { logUniqueWARNING("Definition of services in \"mm\" is deprecated"); } if (unit().compare("g") == 0) { elementToDeploy = new Element(*this, gramsMultiplier); } outputObject.addElement(elementToDeploy); break; } } } } }
double MaterialObject::Element::quantityInUnit(const std::string desiredUnit, const double length, const double surface) const { double returnVal = 0; double density = materialTab_.density(elementName()); bool invert; Unit desiredUnitVal, elementUnitVal, tempUnit; //Conversion matrix: // g g/m mm // __________________________________________________ // g | 1 l/1000 rho*S | // g/m | 1000/l 1 (rho*S*1000)/l | // mm | 1/(rho*S) l/(rho*S*1000) 1 | // // rows: desired unit // columns: original unit // l: length // rho: density // S: surface /* std::map<std::pair<Unit, Unit>, double> conversionMatrix = { {{GRAMS, GRAMS}, 1}, {{GRAMS, GRAMS_METER}, length/1000}, {{GRAMS, MILLIMETERS}, density*surface}, {{GRAMS_METER, GRAMS}, 1000/length}, {{GRAMS_METER, GRAMS_METER}, 1}, {{GRAMS_METER, MILLIMETERS}, (density*surface*1000)/length}, {{MILLIMETERS, GRAMS}, 1/(density*surface)}, {{MILLIMETERS, GRAMS_METER}, length/(density*surface*1000)}, {{MILLIMETERS, MILLIMETERS}, 1} }; try { returnVal = quantity() * conversionMatrix.at({unitStringMap.at(desiredUnit), unitStringMap.at(unit())}); } catch (const std::out_of_range& ex) { logERROR(msg_no_valid_unit + unit() + ", " + desiredUnit + "."); } */ try { desiredUnitVal = unitStringMap.at(desiredUnit); elementUnitVal = unitStringMap.at(unit()); if (desiredUnitVal == elementUnitVal) { return quantity(); } else if (desiredUnitVal > elementUnitVal) { invert = true; tempUnit = desiredUnitVal; desiredUnitVal = elementUnitVal; elementUnitVal = tempUnit; } else { invert = false; } if ((desiredUnitVal == GRAMS) && (elementUnitVal == GRAMS_METER)) returnVal = quantity() * length / 1000.; else if ((desiredUnitVal == GRAMS) && (elementUnitVal == MILLIMETERS)) returnVal = quantity() * density * surface; else if ((desiredUnitVal == GRAMS_METER) && (elementUnitVal == MILLIMETERS)) returnVal = quantity() * (density * surface * 1000.) / length; if (invert) returnVal = 1 / returnVal; } catch (const std::out_of_range& ex) { logERROR(msg_no_valid_unit + unit() + ", " + desiredUnit + "."); } return returnVal; }
void ConversionStation::routeConvertedElements(MaterialObject& localOutput, MaterialObject& serviceOutput, InactiveElement& inactiveElement) { MaterialObject::Element* inputElement; //double totalGrams = 0.0; double multiplier = 0.0; bool converted = false; std::set<std::string> warningMaterials; for (const MaterialObject::Element* currElement : serviceElements_) { //inputElements) { converted = false; //if the material need to be converted (flange station, or endcap station with right destination) if ((stationType_ == FLANGE) || (stationType_ == SECOND && currElement->destination.state() && currElement->destination().compare(stationName_()) == 0)) { for (const Conversion* currConversion : conversions) { inputElement = currConversion->input->elements[0]; if (inputElement->elementName().compare(currElement->elementName()) == 0) { converted = true; multiplier = currElement->quantityInUnit(inputElement->unit(), inactiveElement) / inputElement->quantityInUnit(inputElement->unit(), inactiveElement); for (const MaterialObject::Element* outputElement : currConversion->outputs->elements) { MaterialObject::Element * newElement = new MaterialObject::Element(*outputElement, multiplier); if(currElement->debugInactivate()) { //apply the inactivation also to converteds newElement->debugInactivate(true); } //TODO: check if is ok to do this if(currElement->destination.state() && !newElement->destination.state()) { //apply the same destination of converted element (only if not defined in output conversion rule) newElement->destination(currElement->destination()); } if (newElement->service()) { if (newElement->unit().compare("g") != 0) { serviceOutput.addElement(newElement); } else { logERROR(err_service1 + newElement->elementName() + err_service2); } } else { localOutput.addElement(newElement); } } } } } if (!converted) { serviceOutput.addElement(currElement); warningMaterials.insert(currElement->elementName()); } } for(auto& warningMaterial : warningMaterials) { logWARNING("Element \"" + warningMaterial + "\" ignored by station \"" + stationName_() + "\"."); } /* for (const Conversion* currConversion : conversions) { inputElement = currConversion->input->elements[0]; totalGrams = 0.0; for (const MaterialObject::Element* currElement : inputElements) { if (inputElement->elementName().compare(currElement->elementName()) == 0) { totalGrams += currElement->quantityInGrams(inactiveElement); } } multiplier = totalGrams / inputElement->quantityInGrams(inactiveElement); for (const MaterialObject::Element* outputElement : currConversion->outputs->elements) { MaterialObject::Element * newElement = new MaterialObject::Element(*outputElement, multiplier); if (newElement->service()) { serviceOutput.addElement(newElement); } else { localOutput.addElement(newElement); } } } */ }