How to restore connections when recreating replicants

I am using a Replicator COMP to create several rectangles, each a different size and in a different position based on data from a Table DAT. These are then composited together using a Composite TOP and the output is composited over a base map graphic.

When the Table DAT is changed, the number of rectangles required may go up or down so I need to use the ‘recreate all operators’ function of the Replicator COMP. When I do this all of the output connections from the replicants to the Composite TOP are lost.

How can I restore the output connections for the new replicants?

There are a couple of ways to tackle this…

The composite TOP allows for pattern matching these days, and that’s the option I would recommend. You can also script the wiring process in the callbacks of your replicator COMP, though that can get a bit messy if you’re not careful.

Here’s a look at both solutions:
base_replicator_options_099.tox (1.62 KB)

Thanks, Matthew!

The line in the callbacks DAT works like a charm! Now my replicator is reacting to the changes in my table DAT and all connections are maintained!

The next step is to figure out how to get the needed data from another program (EMS) into TD to automate the whole thing.

I’ll post the finished .toe file when I’m done!

FYI… I’m totally self taught on TD by watching all of your tutorials!

thanks again

Glad to hear that did the trick for you!

I have been able to get an XML file out of my EMS program and using a series of DATs (FileIn, XML, Select, Substitute) I now have the data I need in a single column with a blank row between the needed groups of data. However, I want to transpose this data into a table of rows and columns. Each row needs to contain 5 elements from the original column with row 1 starting at index 1, row 2 at index 7, row 3 at index 13, etc.

I have used a SelectDAT with a rowindexstart of 1 and an rowindexend of rowindexstart+4 to give me a single row containing the first 5 rows from the original column arranged nicely into columns.

How do I create a process (Replicator?) to repeat this step and increase the rowindexstart by 6 each time?

I know that once done I will need to merge all of my single row tables together to create my final data table.

Can you post an example of this?

Python for sure would be a solution if you just need to build a table - if you want something updating in real time it might be a slightly different approach.

Here is the .toe file with the DATs I am using as well as the XML file for the FileInDAT.

DataExample1.toe (4 KB)
Event Schedule.xml (12.5 KB)

The project I am working on is a map of rooms in a conference center which is composed of rooms with moveable walls.

The data table will provide the list of rooms, clients, times, meeting names at the start of each day. This is then used to draw the map of rooms in use for the day by referencing a TableDAT which contains all possible room configurations and selecting out only those in use for the day.

The schedule would be created once per day, in the morning so no real-time updates would be needed. However, I could imagine wanting to be able to CANCEL a meeting or change it during the day so might need a way to update the map at that time.

Also, room configurations might change at some time during the day for meetings later in the evening that require different room layouts.

Here is the map file so you can see what the final product will look like. Included in the zip file are:

SelfAdjustingMap8.toe
BaseMap2.png - used in the MovieFileInTOP

SelfAdjustingMap.zip (13.3 KB)

Here’s a python solution:

[code]target_table = op( ‘table1’ )
source_table = op( ‘select3’ )

target_table.clear()
rowOffset = 0

for tableRow in range( int( source_table.numRows / 5 ) ):

startTime 	= source_table[rowOffset, 0]
endTime		= source_table[rowOffset + 1, 0]
line1 		= source_table[rowOffset + 2, 0]
line2 		= source_table[rowOffset + 3, 0]
room 		= source_table[rowOffset + 4, 0]
newLine 	= [ startTime, endTime, line1, line2, room ]

target_table.appendRow( newLine )

rowOffset  += 6[/code]

base_schedule.tox (2.12 KB)

This would need some error handling to make sure it didn’t break, or if there were any inconsistencies in the incoming xlm, but it’s a start for you.

Also worth pointing out that you can do this with just DATs to parse the XML and then re-assemble a table with the data you want.

base_schedule_just_dats.tox (1.55 KB)

Thanks!

Leaving work now so will look into this in detail tomorrow!

Thanks, Matthew!

I guess my next project is to learn python!

Does the code you wrote run automatically when a new XML file is read in…or do I need some method to run it?

The right way to really do this with python would be to do the parsing here as well. That would look like:

[code]# example by matthew ragan

matthewragan.com

import xml.etree.ElementTree as ET

setting up some variables for our script to use

source = op( ‘text1’ ).text
targetTable = op( ‘table_target’ )
root = ET.fromstring( source )

the number of entires in the XML

numEntries = len(root)

our header names for our targetTable

tableHeader = [ ‘start’,
‘end’,
‘client’,
‘event_name’,
‘room’]

set up our target table

targetTable.clear()
targetTable.appendRow( tableHeader )

for child in root:
# child[1] is start
# child[2] is end
# child[3] is client
# child[4] is event name
# child[5] is room
newRow = [ child[1].text,
child[2].text,
child[3].text,
child[4].text,
child[5].text,]

targetTable.appendRow(newRow)[/code]

base_schedul_pure_python.tox (1.92 KB)

I’d probably lean on using the DAT Only method unless you want a code-centric solution. This new script better handles entries in a correct way - unlike the other table parsing method which could fall victim to oddities in your incoming XML.

This script isn’t set-up to run automatically, so you’ll just need an execute DAT or CHOP to trigger the script.

Hope this helps!

Thanks again, Matthew!

I’m using the DATs only method and am able to get a good table of rooms in use for the day.

Now I need to access the SIZEX SIZEY POSX POSY TEXTSIZE data in my table of all possible rooms configs. I was thinking the best idea is to run a script that compares the room names from the master list to the room list for today and, if they match, update the MEETING BOOKED column in the master list to a value of 1…and if they don’t match set that value to 0. This would allow me to use the existing network to select only the rooms with a 1 in column 6 to be replicated.

Here’s my first, nonworking attempt at a script to do this:

[code]# script to change column 6 value in table1

t1 = op(‘table1’)
t2 = op(‘select1’)

for item in range (t1.numRows):

for item in range (t2.numRows):
	
	if t1[0, 0] == t2[0, 0]:
		t1[0,6] = 1
		
else:

	t1[0,6]= 0[/code]

I think this is working but only on ROW 0 COLUMN 0…and I can see why! But I don’t know how to make the row numbers follow the item in the range…(does that make sense?)

Your help is greatly appreciated!

I tried the following after writing the previous post thinking I had had a flash of insight… I was wrong.

[code]# script to change column 6 value in table1

t1 = op(‘table1’)
t2 = op(‘select1’)

for item in range (t1.numRows):

for item in range (t2.numRows):
	
	if t1[item, 0] == t2[item, 0]:
		t1[item,6] = 1
		
else:

	t1[item,6]= 0[/code]

Are you looking to display if a room is booked during a given block of time or just if it’s been booked during the day?

Your nested for loops mean that you run your second loop as many times as you have rows in t1.

Based on what you’re saying it sounds more like you need a second table with the rooms, and time for the day. You’d loop through your scheduled list, then fill in your second table based on matching time and room hits. This would likely be easier if you change your times to 24 hour bases instead of am/pm - at least for your internal checks.

It might look something like this:
base_booking_table.tox (1.04 KB)

The primary focus of my project is to draw a room map which reflects the room configurations (wall arrangments) based on the daily schedule output of EMS. We already have a table-based display of the meetings/rooms/times for the day. The problem we are trying to solve is that attendees of the meetings don’t know where the rooms are.

For example:

There are 2 rooms called Cougar A and Cougar B and a third room next to them called Spartans. Each of these rooms can be booked individually and would show up on the map as such. The doors to these rooms have signs outside to identify them. However, we can also book a “room” called Cougar Combo which is comprised of all 3 rooms (Cougar A, Cougar B and Spartans). The signs outside the doors still say Cougar A, Cougar B and Spartans so attendees are confused as they are looking for something called Cougar Combo.

The SelfAdjustingMap8.toe I sent you shows how we will draw the map based on which “room” configurations are in use. I can see that we will have to have some sort of time-based method to redraw the map to reflect possible configuration changes that occur during the day. That will be phase 2.

Thanks to your assistance, I have been able to take an XML file exported from EMS and bring it into TD, parse it and get out the data I need (which at this time is primarily the name of the “room” that is booked). The task now is to compare each line item (room name) to the list of “rooms” in the master list and if it matches make the value in column 6 equal to 1. If not make it equal to 0. Doing this will allow me to use the existing network in SelfAdjustingMap8.toe to draw the map. I will just need to link my processed data to the master list so column 6 will be modified.

Am I on the right track? The nested loop script I wrote does not seem to work although I am not getting any script errors. Am I correct in thinking that my problem is the use of the word “item” in both loops?

I think you’re on the right track, I’m just guessing that you’ll end up needing to resolve overlapping times. Which is to say that asking if a room is booked at 1:00 is different than asking if a room is booked today. It sounds like you might be handling this in Phase2 - my suggestion here would be to take some time to think through what that might look like so you don’t program yourself into a corner.

When it comes to loops in loops you can reuse the same variable name, and that will mostly work… though it can cause some unintentional errors. Using a new variable name will make it easier to complete logical tests, as otherwise you’ll end up with some frustrating results. Here’s a quick look at how that can be a little murky:
base_loops_in_loops.tox (774 Bytes)

I think part of what you want is the col() method of the table DAT class. This creates a list of the contents of a given column, making it easier to do a comparison:

[code]# example by matthew ragan

matthewragan.com

booking = op( ‘table_booking’ )
schedule = op( ‘table_schedule’ )
booked_rooms = schedule.col(4)

reset the booking column

for room in range(booking.numRows)[1:]:
booking[room, 6] = 0

loop through the rooms

for room in range(booking.numRows)[1:]:
#check to see if the room is in the list of booked rooms
if booking[room, 0] in booked_rooms:
# if true, mark the room as booked
booking[room, 6] = 1
[/code]

In practice, that might work like this:
base_schedule_room_comparison.tox (1.78 KB)

Matthew -

Thanks for clarifying the formatting of the clock CHOP! I’m using the CHOP replace method you described. I had created a sub-network just to format the minutes display…now it is a single textTOP! BTW… if you know how to include that conversation in this thread please add it.

Next question: (please note I did not say LAST question :wink: )

Is there a way to force a carriage return/line feed in a line of text? I’m assuming you could embed a special character code. Or… is it better practice to use the word-wrap feature in the textTOP and set the width to one that breaks the line where you want it?

Andy