00001 #ifndef PSCALIB_GEOMETRYACCESS_H 00002 #define PSCALIB_GEOMETRYACCESS_H 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: GeometryAccess.h 12031 2016-06-06 21:57:34Z dubrovin@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class GeometryAccess. 00010 // 00011 //------------------------------------------------------------------------ 00012 00013 //----------------- 00014 // C/C++ Headers -- 00015 //----------------- 00016 #include <string> 00017 #include <vector> 00018 #include <map> 00019 #include <boost/shared_ptr.hpp> 00020 00021 //---------------------- 00022 // Base Class Headers -- 00023 //---------------------- 00024 00025 //------------------------------- 00026 // Collaborating Class Headers -- 00027 //------------------------------- 00028 #include "PSCalib/GeometryObject.h" 00029 00030 #include "ndarray/ndarray.h" // for img_from_pixel_arrays(...) 00031 00032 //------------------------------------ 00033 // Collaborating Class Declarations -- 00034 //------------------------------------ 00035 00036 // --------------------- 00037 // -- Class Interface -- 00038 // --------------------- 00039 00040 namespace PSCalib { 00041 00042 /// @addtogroup PSCalib 00043 00044 /** 00045 * @ingroup PSCalib 00046 * 00047 * @brief Class supports universal detector geometry description. 00048 * 00049 * This software was developed for the LCLS project. If you use all or 00050 * part of it, please give an appropriate acknowledgment. 00051 * 00052 * @version $Id: GeometryAccess.h 12031 2016-06-06 21:57:34Z dubrovin@SLAC.STANFORD.EDU $ 00053 * 00054 * @see GeometryObject, CalibFileFinder, PSCalib/test/ex_geometry_access.cpp 00055 * 00056 * @anchor interface 00057 * @par<interface> Interface Description 00058 * 00059 * @li Include 00060 * @code 00061 * #include "PSCalib/GeometryAccess.h" 00062 * #include "ndarray/ndarray.h" // need it if image is returned 00063 * @endcode 00064 * 00065 * @li Instatiation 00066 * \n 00067 * Code below instateates GeometryAccess object using path to the calibration "geometry" file and verbosity control bit-word: 00068 * @code 00069 * std::string path = /reg/d/psdm/<INS>/<experiment>/calib/<calib-type>/<det-src>/geometry/0-end.data" 00070 * unsigned print_bits = 0377; // or = 0 (by default) - to suppress printout from this object. 00071 * PSCalib::GeometryAccess geometry(path, print_bits); 00072 * @endcode 00073 * To find path automatically use CalibFileFinder. 00074 * 00075 * @li Access methods 00076 * @code 00077 * // Access and print coordinate arrays: 00078 * const double* X; 00079 * const double* Y; 00080 * const double* Z; 00081 * unsigned size; 00082 * bool do_tilt=true; 00083 * geometry.get_pixel_coords(X,Y,Z,size); 00084 * cout << "size=" << size << '\n' << std::fixed << std::setprecision(1); 00085 * cout << "X: "; for(unsigned i=0; i<10; ++i) cout << std::setw(10) << X[i] << ", "; cout << "...\n"; 00086 * // or get coordinate arrays for specified geometry object: 00087 * geometry.get_pixel_coords(X,Y,Z,size, "QUAD:V1", 1, do_tilt); 00088 * // then use X, Y, Z, size 00089 * 00090 * // Access pixel X,Y coordinate [um] arrays projected toward origin on specified zplane, if zplane=0 then zplane is averaged Z: 00091 * const double Zplane=12345; //[um] or 0 00092 * geometry.get_pixel_xy_at_z(X,Y,size,Zplane); 00093 * 00094 * // Access pixel areas: 00095 * const double* A; 00096 * unsigned size; 00097 * geometry.get_pixel_areas(A,size); 00098 * 00099 * // Access pixel mask: 00100 * const int* mask; 00101 * unsigned size; 00102 * unsigned mbits=0377; // 1-edges; 2-wide central cols; 4-non-bound; 8-non-bound neighbours 00103 * geometry.get_pixel_mask(A, size, std::string(), 0, mbits); 00104 * 00105 * // Access pixel size for entire detector: 00106 * double pix_scale_size = geometry.get_pixel_scale_size (); 00107 * // or for specified geometry object, for example one quad of CSPAD 00108 * double pix_scale_size = geometry.get_pixel_scale_size("QUAD:V1", 1); 00109 * 00110 * // Access pixel indexes for image: 00111 * const unsigned * iX; 00112 * const unsigned * iY; 00113 * unsigned isize; 00114 * // optional parameters for specified geometry 00115 * const std::string ioname = "QUAD:V1"; 00116 * const unsigned ioindex = 1; 00117 * const double pix_scale_size_um = 109.92; 00118 * const int xy0_off_pix[] = {200,200}; 00119 * 00120 * // this call returns index arrays iX, iY of size=isize for QUAD with offset 00121 * geometry.get_pixel_coord_indexes(iX, iY, isize, ioname, ioindex, pix_scale_size_um, xy0_off_pix, do_tilt); 00122 * 00123 * // this call returns index arrays for entire detector with auto generated minimal offset 00124 * geometry.get_pixel_coord_indexes(iX, iY, isize); 00125 * // then use iX, iY, isize, for example make image as follows. 00126 * 00127 * // Access pixel iX, iY indexes for projected to specified z-plane coordinates: 00128 * const double Zplane=12345; //[um] or 0 00129 * geometry.get_pixel_xy_inds_at_z(iX, iY, isize, Zplane); 00130 * 00131 * // Make image from index, iX, iY, and intensity, W, arrays 00132 * ndarray<PSCalib::GeometryAccess::image_t, 2> img = 00133 * PSCalib::GeometryAccess::img_from_pixel_arrays(iX, iY, 0, isize); 00134 * 00135 * // Access and print comments from the calibration "geometry" file: 00136 * std::map<int, std::string>& dict = geometry.get_dict_of_comments (); 00137 * cout << "dict[0] = " << dict[0] << '\n'; 00138 * @endcode 00139 * 00140 * @li Print methods 00141 * @code 00142 * geometry.print_pixel_coords(); 00143 * geometry.print_pixel_coords("QUAD:V1", 1); 00144 * geometry.print_list_of_geos(); 00145 * geometry.print_list_of_geos_children(); 00146 * geometry.print_comments_from_dict(); 00147 * 00148 * // or print info about specified geometry objects (see class GeometryObject): 00149 * geometry.get_geo("QUAD:V1", 1)->print_geo(); 00150 * geometry.get_top_geo()->print_geo_children(); 00151 * @endcode 00152 * 00153 * @li Modify and save new geometry file methods 00154 * @code 00155 * geometry.set_geo_pars("QUAD:V1", x0, y0, z0, rot_z,...<entire-list-of-9-parameters>); 00156 * geometry.move_geo("QUAD:V1", 1, 10, 20, 0); 00157 * geometry.tilt_geo("QUAD:V1", 1, 0.01, 0, 0); 00158 * geometry.save_pars_in_file("new-file-name.txt"); 00159 * @endcode 00160 * 00161 * @author Mikhail S. Dubrovin 00162 */ 00163 00164 00165 class GeometryAccess { 00166 00167 //typedef boost::shared_ptr<GeometryObject> shpGO; 00168 /** Use the same declaration of the shared pointer to geometry object like in the class GeometryObject*/ 00169 typedef PSCalib::GeometryObject::shpGO shpGO; 00170 00171 public: 00172 00173 typedef double image_t; 00174 00175 /** 00176 * @brief Class constructor accepts path to the calibration "geometry" file and verbosity control bit-word 00177 * 00178 * @param[in] path path to the calibration "geometry" file 00179 * @param[in] pbits verbosity control bit-word; 00180 * \n =0 print nothing, 00181 * \n +1 info about loaded file, 00182 * \n +2 list of geometry objects, 00183 * \n +8 list of geometry objects with childrens, 00184 * \n +16 info about setting relations between geometry objects, 00185 * \n +32 info about pixel coordinate reconstruction 00186 */ 00187 GeometryAccess(const std::string& path, unsigned pbits=0) ; 00188 00189 // Destructor 00190 virtual ~GeometryAccess () ; 00191 00192 /// Returns shared pointer to the geometry object specified by name and index 00193 shpGO get_geo(const std::string& oname, const unsigned& oindex); 00194 00195 /// Returns shared pointer to the top geometry object, for exampme CSPAD 00196 shpGO get_top_geo(); 00197 00198 /// Returns pixel coordinate arrays X, Y, Z, of size for specified geometry object 00199 /** 00200 * @param[out] X - pointer to x pixel coordinate array 00201 * @param[out] Y - pointer to y pixel coordinate array 00202 * @param[out] Z - pointer to z pixel coordinate array 00203 * @param[out] size - size of the pixel coordinate array (number of pixels) 00204 * @param[in] oname - object name 00205 * @param[in] oindex - object index 00206 * @param[in] do_tilt - on/off tilt angle correction 00207 * @param[in] do_eval - update all evaluated arrays 00208 */ 00209 void get_pixel_coords(const double*& X, 00210 const double*& Y, 00211 const double*& Z, 00212 unsigned& size, 00213 const std::string& oname = std::string(), 00214 const unsigned& oindex = 0, 00215 const bool do_tilt=true, 00216 const bool do_eval=false); 00217 00218 /// Returns pixel coordinate arrays XatZ, YatZ, of size for specified Zplane and geometry object 00219 /** 00220 * @param[out] XatZ - pointer to x pixel coordinate array at specified Zplane 00221 * @param[out] YatZ - pointer to y pixel coordinate array 00222 * @param[out] size - size of the pixel coordinate array (number of pixels) 00223 * @param[in] Zplane - z-coordinate of the plane for projection 00224 * @param[in] oname - object name 00225 * @param[in] oindex - object index 00226 */ 00227 void get_pixel_xy_at_z(const double*& XatZ, 00228 const double*& YatZ, 00229 unsigned& size, 00230 const double& Zplane = 0, 00231 const std::string& oname = std::string(), 00232 const unsigned& oindex = 0); 00233 00234 /// Returns pixel areas array A, of size for specified geometry object 00235 /** 00236 * @param[out] A - pointer to pixel areas array 00237 * @param[out] size - size of the pixel array (number of pixels) 00238 * @param[in] oname - object name 00239 * @param[in] oindex - object index 00240 */ 00241 void get_pixel_areas(const double*& A, 00242 unsigned& size, 00243 const std::string& oname = std::string(), 00244 const unsigned& oindex = 0); 00245 00246 /// Returns pixel mask array of size for specified geometry object 00247 /** 00248 * @param[out] mask - pointer to pixel mask array 00249 * @param[out] size - size of the pixel array (number of pixels) 00250 * @param[in] oname - object name 00251 * @param[in] oindex - object index 00252 * @param[in] mbits - mask control bits; 00253 * +1-mask edges, 00254 * +2-two wide central columns, 00255 * +4-non-bounded, 00256 * +8-non-bounded neighbours. 00257 */ 00258 void get_pixel_mask(const int*& mask, 00259 unsigned& size, 00260 const std::string& oname = std::string(), 00261 const unsigned& oindex = 0, 00262 const unsigned& mbits = 0377); 00263 00264 /// Returns pixel scale size for specified geometry object through its children segment 00265 /** 00266 * @param[in] oname - object name 00267 * @param[in] oindex - object index 00268 */ 00269 double get_pixel_scale_size(const std::string& oname = std::string(), 00270 const unsigned& oindex = 0); 00271 00272 /// Returns dictionary of comments 00273 //std::map<std::string, std::string>& get_dict_of_comments() {return m_dict_of_comments;} 00274 std::map<int, std::string>& get_dict_of_comments() {return m_dict_of_comments;} 00275 00276 /// Prints the list of geometry objects 00277 void print_list_of_geos(); 00278 00279 /// Prints the list of geometry objects with children 00280 void print_list_of_geos_children(); 00281 00282 /// Prints comments loaded from input file and kept in the dictionary 00283 void print_comments_from_dict(); 00284 00285 /// Prints beginning of pixel coordinate arrays for specified geometry object (top object by default) 00286 void print_pixel_coords(const std::string& oname= std::string(), 00287 const unsigned& oindex = 0); 00288 00289 /// Returns pixel coordinate index arrays iX, iY of size for specified geometry object 00290 /** 00291 * @param[out] iX - pointer to x pixel index coordinate array 00292 * @param[out] iY - pointer to y pixel index coordinate array 00293 * @param[out] size - size of the pixel coordinate array (number of pixels) 00294 * @param[in] oname - object name (deafault - top object) 00295 * @param[in] oindex - object index (default = 0) 00296 * @param[in] pix_scale_size_um - ex.: 109.92 (default - search for the first segment pixel size) 00297 * @param[in] xy0_off_pix - array containing X and Y coordinates of the offset (default - use xmin, ymin) 00298 * @param[in] do_tilt - on/off tilt angle correction 00299 */ 00300 void get_pixel_coord_indexes(const unsigned *& iX, 00301 const unsigned *& iY, 00302 unsigned& size, 00303 const std::string& oname = std::string(), 00304 const unsigned& oindex = 0, 00305 const double& pix_scale_size_um = 0, 00306 const int* xy0_off_pix = 0, 00307 const bool do_tilt=true ); 00308 00309 /// Returns pixel coordinate index arrays iX, iY of size for specified Zplane and geometry object 00310 /** 00311 * @param[out] iX - pointer to x pixel index coordinate array 00312 * @param[out] iY - pointer to y pixel index coordinate array 00313 * @param[out] size - size of the pixel coordinate array (number of pixels) 00314 * @param[in] Zplane - z-coordinate of the plane for projection (default=0 - evaluated as average z ovetr all pixels) 00315 * @param[in] oname - object name (deafault - top object) 00316 * @param[in] oindex - object index (default = 0) 00317 * @param[in] pix_scale_size_um - ex.: 109.92 (default - search for the first segment pixel size) 00318 * @param[in] xy0_off_pix - array containing X and Y coordinates of the offset (default - use xmin, ymin) 00319 */ 00320 void get_pixel_xy_inds_at_z(const unsigned *& iX, 00321 const unsigned *& iY, 00322 unsigned& size, 00323 const double& Zplane = 0, 00324 const std::string& oname = std::string(), 00325 const unsigned& oindex = 0, 00326 const double& pix_scale_size_um = 0, 00327 const int* xy0_off_pix = 0); 00328 00329 /// Static method returns image as ndarray<image_t, 2> object 00330 /** 00331 * @param[in] iX - pointer to x pixel index coordinate array 00332 * @param[in] iY - pointer to y pixel index coordinate array 00333 * @param[in] W - pointer to the intensity (weights) array (default - set 1 for each pixel) 00334 * @param[in] size - size of the pixel coordinate array (number of pixels) 00335 */ 00336 static ndarray<image_t, 2> 00337 img_from_pixel_arrays(const unsigned*& iX, 00338 const unsigned*& iY, 00339 const double* W = 0, 00340 const unsigned& size = 0); 00341 00342 /// Returns pointer to the data member ndarray<image_t, 2> image object 00343 ndarray<image_t, 2>& 00344 ref_img_from_pixel_arrays(const unsigned*& iX, 00345 const unsigned*& iY, 00346 const double* W = 0, 00347 const unsigned& size = 0); 00348 00349 /// Loads calibration file 00350 /** 00351 * @param[in] path - path to the file with calibration parameters of type "geometry" 00352 */ 00353 void load_pars_from_file(const std::string& path = std::string()); 00354 00355 /// Saves calibration file 00356 /** 00357 * @param[in] path - path to the file with calibration parameters of type "geometry" 00358 */ 00359 void save_pars_in_file(const std::string& path = std::string()); 00360 00361 /// Sets the m_pbits - printout control bitword 00362 /** 00363 * @param[in] pbits - printout control bitword 00364 */ 00365 void set_print_bits(unsigned pbits=0) {m_pbits=pbits;} 00366 00367 /// Sets self object geometry parameters 00368 void set_geo_pars(const std::string& oname = std::string(), 00369 const unsigned& oindex = 0, 00370 const double& x0 = 0, 00371 const double& y0 = 0, 00372 const double& z0 = 0, 00373 const double& rot_z = 0, 00374 const double& rot_y = 0, 00375 const double& rot_x = 0, 00376 const double& tilt_z = 0, 00377 const double& tilt_y = 0, 00378 const double& tilt_x = 0 00379 ); 00380 00381 /// Adds offset for origin of the self object w.r.t. current position 00382 void move_geo(const std::string& oname = std::string(), 00383 const unsigned& oindex = 0, 00384 const double& dx = 0, 00385 const double& dy = 0, 00386 const double& dz = 0 00387 ); 00388 00389 /// Adds tilts to the self object w.r.t. current orientation 00390 void tilt_geo(const std::string& oname = std::string(), 00391 const unsigned& oindex = 0, 00392 const double& dt_x = 0, 00393 const double& dt_y = 0, 00394 const double& dt_z = 0 00395 ); 00396 00397 protected: 00398 00399 private: 00400 00401 /// path to the calibration "geometry" file 00402 std::string m_path; 00403 00404 /// print bits 00405 unsigned m_pbits; 00406 00407 /// pointer to x pixel coordinate index array 00408 unsigned* p_iX; 00409 00410 /// pointer to y pixel coordinate index array 00411 unsigned* p_iY; 00412 00413 /// Pointer to image, which is created as a member data of GeometryAccess object 00414 ndarray<image_t, 2>* p_image; 00415 00416 /// pointer to array of x pixel coordinates centrally projected to specified z plane 00417 double* p_XatZ; 00418 00419 /// pointer to array of y pixel coordinates centrally projected to specified z plane 00420 double* p_YatZ; 00421 00422 /// vector/list of shared pointers to geometry objects 00423 std::vector<shpGO> v_list_of_geos; 00424 00425 /// map/dictionary of comments from calibration "geometry" file 00426 //std::map<std::string, std::string> m_dict_of_comments; 00427 std::map<int, std::string> m_dict_of_comments; 00428 00429 /// Adds comment to the dictionary 00430 void add_comment_to_dict(const std::string& line); 00431 00432 /// Parses input data line, creates and returns geometry object 00433 shpGO parse_line(const std::string& line); 00434 00435 /// Returns shp to the parent of geobj. If parent is not found adds geobj as a top parent and returns 0. 00436 shpGO find_parent(const shpGO& geobj); 00437 00438 /// Set relations between geometry objects in the list_of_geos 00439 void set_relations(); 00440 00441 /// Returns class name for MsgLogger 00442 static const std::string name() {return "PSCalib";} 00443 00444 // Copy constructor and assignment are disabled by default 00445 GeometryAccess(const GeometryAccess&) ; 00446 GeometryAccess& operator = (const GeometryAccess&) ; 00447 00448 //----------------------------- 00449 }; 00450 00451 } // namespace PSCalib 00452 00453 #endif // PSCALIB_GEOMETRYACCESS_H