00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_VISX_TLISTUTILS_CC_UTC20050626084015_DEFINED
00035 #define GROOVX_VISX_TLISTUTILS_CC_UTC20050626084015_DEFINED
00036
00037 #include "tlistutils.h"
00038
00039 #include "geom/rect.h"
00040
00041 #include "gfx/gxaligner.h"
00042 #include "gfx/gxscaler.h"
00043 #include "gfx/gxseparator.h"
00044 #include "gfx/gxshapekit.h"
00045 #include "gfx/gxtext.h"
00046 #include "gfx/gxtransform.h"
00047
00048 #include "io/writer.h"
00049
00050 #include "nub/objdb.h"
00051 #include "nub/ref.h"
00052
00053 #include "tcl/list.h"
00054
00055 #include "rutz/arrays.h"
00056 #include "rutz/cstrstream.h"
00057 #include "rutz/error.h"
00058 #include "rutz/iter.h"
00059 #include "rutz/sfmt.h"
00060
00061 #include "visx/trial.h"
00062
00063 #include <fstream>
00064 #include <iomanip>
00065 #include <vector>
00066
00067 #include "rutz/trace.h"
00068
00069 using nub::ref;
00070
00071 namespace
00072 {
00073 nub::uid doCreatePreview(const geom::rect<double>& world_viewport,
00074 nub::uid* objids,
00075 unsigned int objids_size,
00076 int num_cols_hint = -1,
00077 bool text_labels = true)
00078 {
00079 GVX_TRACE("<tlisttcl.cc>::doCreatePreview");
00080
00081 if (world_viewport.is_void())
00082 throw rutz::error("invalid void rect", SRC_POS);
00083
00084 const double world_width = world_viewport.width();
00085 const double world_height = world_viewport.height();
00086
00087 const double window_area = world_width*world_height;
00088 const double parcel_area = window_area/objids_size;
00089 const double raw_parcel_side = sqrt(parcel_area);
00090
00091 const int num_cols = num_cols_hint > 0
00092 ? num_cols_hint : int(world_width/raw_parcel_side) + 1;
00093
00094 const double parcel_side = world_width/num_cols;
00095
00096 ref<GxSeparator> preview_trial(GxSeparator::make());
00097
00098 int x_step = -1;
00099 int y_step = 0;
00100
00101 for (size_t i = 0; i < objids_size; ++i)
00102 {
00103 ++x_step;
00104 if (x_step == num_cols) { x_step = 0; ++y_step; }
00105
00106 ref<GxShapeKit> obj(objids[i]);
00107
00108 obj->setAlignmentMode(GxAligner::CENTER_ON_CENTER);
00109 obj->setBBVisibility(true);
00110 obj->setScalingMode(GxScaler::MAINTAIN_ASPECT_SCALING);
00111 obj->setMaxDimension(0.8);
00112
00113 ref<GxTransform> obj_pos(GxTransform::make());
00114 double obj_x = -world_width/2.0 + (x_step+0.5)*parcel_side;
00115 double obj_y = world_height/2.0 - (y_step+0.45)*parcel_side;
00116 obj_pos->translation.vec().set(obj_x, obj_y, 0.0);
00117 obj_pos->scaling.vec().set(parcel_side, parcel_side, 1.0);
00118
00119 ref<GxSeparator> obj_pair(GxSeparator::make());
00120 obj_pair->addChild(obj_pos);
00121 obj_pair->addChild(obj);
00122
00123 preview_trial->addChild(obj_pair);
00124
00125 if (text_labels)
00126 {
00127 ref<GxText> label(GxText::make());
00128 label->setText(rutz::sfmt("%lu", objids[i]));
00129 label->setAlignmentMode(GxAligner::CENTER_ON_CENTER);
00130 label->setScalingMode(GxScaler::MAINTAIN_ASPECT_SCALING);
00131 label->setHeight(0.1);
00132
00133 ref<GxTransform> label_pos(GxTransform::make());
00134 double label_x = obj_x;
00135 double label_y = obj_y - 0.50*parcel_side;
00136 label_pos->translation.vec().set(label_x, label_y, 0.0);
00137 label_pos->scaling.vec().set(parcel_side, parcel_side, 1.0);
00138
00139 ref<GxSeparator> label_pair(GxSeparator::make());
00140 label_pair->addChild(label_pos);
00141 label_pair->addChild(label);
00142
00143 preview_trial->addChild(label_pair);
00144 }
00145 }
00146
00147 return preview_trial.id();
00148 }
00149
00150 ref<GxSeparator> makeSepPair(ref<GxNode> obj1, ref<GxNode> obj2)
00151 {
00152 ref<GxSeparator> sep(GxSeparator::make());
00153 sep->addChild(obj1);
00154 sep->addChild(obj2);
00155 return sep;
00156 }
00157
00158 rutz::fstring gsubst(const rutz::fstring& in,
00159 const char match,
00160 const char* const replace)
00161 {
00162 std::vector<char> result;
00163 result.reserve(in.length());
00164
00165 for (const char* p = in.c_str(); *p != '\0'; ++p)
00166 {
00167 if (*p == match)
00168 {
00169 for (const char* q = replace; *q != '\0'; ++q)
00170 result.push_back(*q);
00171 }
00172 else
00173 {
00174 result.push_back(*p);
00175 }
00176 }
00177
00178 result.push_back('\0');
00179
00180 return rutz::fstring(&result[0]);
00181 }
00182 }
00183
00184 void TlistUtils::writeResponses(const char* filename)
00185 {
00186 GVX_TRACE("TlistUtils::writeResponses");
00187
00188 std::ofstream ofs(filename);
00189 const int wid = 8;
00190
00191
00192
00193 ofs << '%' << std::setw(wid-1) << "Trial" << " "
00194 << std::setw(wid) << "N" << " "
00195 << std::setw(wid) << "Average" << " "
00196 << std::setw(wid) << "msec" << " "
00197 << " description\n";
00198
00199 ofs.setf(std::ios::fixed);
00200 ofs.precision(2);
00201
00202 for (nub::objectdb::casting_iterator<Trial> itr(nub::objectdb::instance().objects());
00203 itr.is_valid();
00204 ++itr)
00205 {
00206 ofs << std::setw(wid) << itr->id() << " ";
00207 ofs << std::setw(wid) << itr->numResponses() << " ";
00208 ofs << std::setw(wid) << itr->avgResponse() << " ";
00209 ofs << std::setw(wid) << itr->avgRespTime() << " ";
00210 ofs << "% " << gsubst(itr->vxInfo(), '\n', "\\n") << std::endl;
00211 }
00212
00213 if (ofs.fail())
00214 throw rutz::error("error while writing to file", SRC_POS);
00215 }
00216
00217 void TlistUtils::writeIncidenceMatrix(const char* filename)
00218 {
00219 GVX_TRACE("TlistUtils::writeIncidenceMatrix");
00220
00221 std::ofstream ofs(filename);
00222
00223 for (nub::objectdb::casting_iterator<Trial> itr(nub::objectdb::instance().objects());
00224 itr.is_valid();
00225 ++itr)
00226 {
00227
00228 double fudge = 0.0001;
00229
00230 int num_zeros =
00231 int( (1.0 - itr->avgResponse()) * itr->numResponses() + fudge );
00232
00233 int num_ones = itr->numResponses() - num_zeros;
00234
00235 ofs << num_zeros << " " << num_ones << std::endl;
00236 }
00237 }
00238
00239 class MatlabTrialWriter : public io::writer
00240 {
00241 private:
00242 std::ostream& itsOs;
00243 public:
00244 MatlabTrialWriter(std::ostream& os) : itsOs(os) {}
00245
00246 virtual void write_char(const char*, char) {}
00247 virtual void write_int(const char*, int) {}
00248 virtual void write_bool(const char*, bool) {}
00249 virtual void write_double(const char*, double) {}
00250 virtual void write_value_obj(const char*, const rutz::value&) {}
00251 virtual void write_cstring(const char*, const char*) {}
00252
00253 virtual void write_byte_array(const char*,
00254 const unsigned char*,
00255 unsigned int) {}
00256
00257 virtual void write_object(const char*,
00258 nub::soft_ref<const io::serializable> obj)
00259 {
00260 GVX_TRACE("MatlabTrialWriter::write_object");
00261 if (!obj.is_valid())
00262 return;
00263 if (dynamic_cast<const GxShapeKit*>(obj.get()) != 0)
00264 {
00265 itsOs << obj->id() << ' ';
00266 }
00267 else
00268 {
00269 obj->write_to(*this);
00270 }
00271 }
00272
00273 virtual void write_owned_object(const char* name,
00274 nub::ref<const io::serializable> obj)
00275 {
00276 GVX_TRACE("MatlabTrialWriter::write_owned_object");
00277 write_object(name, obj);
00278 }
00279
00280 virtual void write_base_class(const char*,
00281 nub::ref<const io::serializable> base_part)
00282 {
00283 GVX_TRACE("MatlabTrialWriter::write_base_class");
00284 base_part->write_to(*this);
00285 }
00286
00287 virtual void write_root(const io::serializable* root)
00288 {
00289 GVX_TRACE("MatlabTrialWriter::write_root");
00290 root->write_to(*this);
00291 }
00292 };
00293
00294 void TlistUtils::writeMatlab(const char* filename)
00295 {
00296 GVX_TRACE("TlistUtils::writeMatlab");
00297
00298 std::ofstream ofs(filename);
00299
00300 ofs.setf(std::ios::fixed);
00301 ofs.precision(2);
00302
00303 MatlabTrialWriter writer(ofs);
00304
00305 for (nub::objectdb::casting_iterator<Trial> itr(nub::objectdb::instance().objects());
00306 itr.is_valid();
00307 ++itr)
00308 {
00309 writer.write_root(*itr);
00310 ofs << itr->avgResponse() << '\n';
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 nub::uid TlistUtils::createPreview(tcl::list objid_list,
00321 const geom::rect<double>& world_viewport,
00322 int num_cols_hint = -1,
00323 bool text_labels = true)
00324 {
00325 rutz::fixed_block<nub::uid> objids(objid_list.begin<nub::uid>(),
00326 objid_list.end<nub::uid>());
00327
00328 return doCreatePreview(world_viewport,
00329 &objids[0], objids.size(),
00330 num_cols_hint, text_labels);
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 tcl::list TlistUtils::dealSingles(tcl::list objids, nub::uid posid)
00343 {
00344 tcl::list result;
00345
00346 ref<GxNode> pos(posid);
00347
00348 for (tcl::list::iterator<nub::uid>
00349 itr = objids.begin<nub::uid>(),
00350 end = objids.end<nub::uid>();
00351 itr != end;
00352 ++itr)
00353 {
00354 ref<GxNode> obj(*itr);
00355
00356 ref<Trial> trial(Trial::make());
00357
00358 trial->addNode(makeSepPair(pos, obj));
00359
00360 nub::soft_ref<GxShapeKit> sk(*itr);
00361 if (sk.is_valid())
00362 trial->setType(sk->category());
00363
00364 result.append(trial.id());
00365 }
00366 return result;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 tcl::list TlistUtils::dealPairs(tcl::list objids1, tcl::list objids2,
00376 nub::uid posid1, nub::uid posid2)
00377 {
00378 tcl::list result;
00379
00380 ref<GxNode> pos1(posid1);
00381 ref<GxNode> pos2(posid2);
00382
00383 for (tcl::list::iterator<nub::uid>
00384 itr1 = objids1.begin<nub::uid>(),
00385 end1 = objids1.end<nub::uid>();
00386 itr1 != end1;
00387 ++itr1)
00388 {
00389 ref<GxSeparator> sep1(makeSepPair(pos1, ref<GxNode>(*itr1)));
00390
00391 for (tcl::list::iterator<nub::uid>
00392 itr2 = objids2.begin<nub::uid>(),
00393 end2 = objids2.end<nub::uid>();
00394 itr2 != end2;
00395 ++itr2)
00396 {
00397 ref<GxSeparator> sep2(makeSepPair(pos2, ref<GxNode>(*itr2)));
00398
00399 ref<Trial> trial(Trial::make());
00400
00401 trial->addNode(makeSepPair(sep1, sep2));
00402 trial->setType(*itr1 == *itr2);
00403
00404 result.append(trial.id());
00405 }
00406 }
00407
00408 return result;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 tcl::list TlistUtils::dealTriads(tcl::list objid_list, nub::uid posid1,
00418 nub::uid posid2, nub::uid posid3)
00419 {
00420 const unsigned int NUM_PERMS = 18;
00421 static int permutations[NUM_PERMS][3] =
00422 {
00423 {0, 0, 1},
00424 {0, 0, 2},
00425 {1, 1, 0},
00426 {1, 1, 2},
00427 {2, 2, 0},
00428 {2, 2, 1},
00429 {0, 1, 1},
00430 {0, 2, 2},
00431 {1, 0, 0},
00432 {2, 0, 0},
00433 {2, 1, 1},
00434 {1, 2, 2},
00435 {0, 1, 2},
00436 {0, 2, 1},
00437 {1, 0, 2},
00438 {1, 2, 0},
00439 {2, 0, 1},
00440 {2, 1, 0}
00441 };
00442
00443 rutz::fixed_block<nub::uid> objids(objid_list.begin<nub::uid>(),
00444 objid_list.end<nub::uid>());
00445
00446 nub::uid base_triad[3];
00447
00448 tcl::list result;
00449
00450 for (unsigned int i = 0; i < objids.size(); ++i)
00451 {
00452 base_triad[0] = objids[i];
00453
00454 for (unsigned int j = i+1; j < objids.size(); ++j)
00455 {
00456 base_triad[1] = objids[j];
00457
00458 for (unsigned int k = j+1; k < objids.size(); ++k)
00459 {
00460 base_triad[2] = objids[k];
00461
00462
00463 for (unsigned int p = 0; p < NUM_PERMS; ++p)
00464 {
00465 ref<GxSeparator> sep(GxSeparator::make());
00466
00467 sep->addChild(makeSepPair(
00468 ref<GxNode>(base_triad[permutations[p][0]]),
00469 ref<GxNode>(posid1)));
00470
00471 sep->addChild(makeSepPair(
00472 ref<GxNode>(base_triad[permutations[p][1]]),
00473 ref<GxNode>(posid2)));
00474
00475 sep->addChild(makeSepPair(
00476 ref<GxNode>(base_triad[permutations[p][2]]),
00477 ref<GxNode>(posid3)));
00478
00479 ref<Trial> trial(Trial::make());
00480 trial->addNode(sep);
00481 result.append(trial.id());
00482 }
00483 }
00484 }
00485 }
00486
00487 return result;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496 tcl::list TlistUtils::loadObjidFile(const char* objid_file,
00497 tcl::list objid_list,
00498 tcl::list posid_list, int num_lines)
00499 {
00500
00501
00502 bool read_to_eof = (num_lines < 0);
00503
00504 rutz::fixed_block<nub::uid> objids(objid_list.begin<nub::uid>(),
00505 objid_list.end<nub::uid>());
00506
00507 rutz::fixed_block<nub::uid> posids(posid_list.begin<nub::uid>(),
00508 posid_list.end<nub::uid>());
00509
00510 std::ifstream ifs(objid_file);
00511
00512 if (ifs.fail())
00513 throw rutz::error(rutz::sfmt("couldn't open '%s' for reading",
00514 objid_file), SRC_POS);
00515
00516 const int BUF_SIZE = 200;
00517 char line[BUF_SIZE];
00518
00519 tcl::list result;
00520
00521 int num_read = 0;
00522 while ( (read_to_eof || num_read < num_lines)
00523 && ifs.getline(line, BUF_SIZE) )
00524 {
00525
00526
00527
00528 if (line[0] == '#')
00529 continue;
00530
00531 if (ifs.fail())
00532 throw rutz::error("error reading objid file", SRC_POS);
00533
00534 rutz::icstrstream ist(line);
00535
00536 ref<Trial> trial(Trial::make());
00537 ref<GxSeparator> sep(GxSeparator::make());
00538
00539 int objn = 0;
00540 int posn = 0;
00541 while (ist >> objn)
00542 {
00543 sep->addChild(makeSepPair(ref<GxNode>(posids[posn]),
00544 ref<GxNode>(objids[objn-1])));
00545 ++posn;
00546 }
00547
00548 if (ist.fail() && !ist.eof())
00549 throw rutz::error("error reading objid file", SRC_POS);
00550
00551 trial->addNode(sep);
00552
00553 result.append(trial->id());
00554
00555 ++num_read;
00556 }
00557
00558 return result;
00559 }
00560
00561 static const char __attribute__((used)) vcid_groovx_visx_tlistutils_cc_utc20050626084015[] = "$Id: tlistutils.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00562 #endif // !GROOVX_VISX_TLISTUTILS_CC_UTC20050626084015_DEFINED